Swift:如何重新排序和省略存储在变量中的函数中的参数
Swift: How to reorder and omit parameters in functions stored in variables
我对 Swift 中的函数存储和传递有点熟悉,但是我对该语言在这方面的行为有几个具体问题。
假设我们有一个变量函数 MathOperation:
var mathOperation: (Double, Double) -> Double
现在假设我们将其设置为函数 Subtract:
func subtract (minuend: Double, subtrahend: Double) -> Double {
return minuend - subtrahend
}
mathOperation = subtract
然后我们应该可以用
调用subtract
let result = mathOperation(3, 4.222)
但是,如果我们想传入一个比 mathOperation
声明要求的参数更多或顺序不同的参数怎么办?例如:
func divide (dividend: Double, divisor: Double, roundToInt: Bool = false) -> Double { ... }
如何将 mathOperation
设置为 divide
,从而忽略 roundToInt
?
此外,是否可以重新排列参数?假设我们在无法修改的库中有一个求幂函数:
func exponentiate (power: Double, base: Double) -> Double { ... }
在base之前有power是不常见的,假设使用mathOperation
的地方,我们需要像用(base: Double, power: Double)
声明的那样调用它。
有没有办法把mathOperation
设置成exponentiate
,这样调用的时候参数就反转了?
最后一个问题。假设我们有一个插值函数,我们想将 mathOperation
设置为:
func interpolate (start: Double, end: Double, by: Double, nonlinearity: (Double) -> Double) -> Double { ... }
有没有办法将 mathOperation
设置为 interpolate
以便
mathOperation (a, b)
结果
interpolate (start: a, end: b, by: 0.5, nonlinearity: { [=18=] })
如果其中任何一个是可能的,那么如果有人可以指导我找到对此进行解释的官方文档,那将是理想的。
对于您的插值案例(其他案例如下)只需定义以下内容:
mathOperation = { interpolate (start: [=10=], end: , by: 0.5, nonlinearity: { [=10=] })}
本质上,您将 interpolate
包装在一个闭包中,其中一些参数是固定的,例如本例中的 by
到 0.5
。 (这称为“partial application”)
您还可以将其归纳为如下内容:
func interpolateToMathOperation (by: Double, nonlinearity: @escaping (Double) -> Double) -> (Double, Double) -> Double {
return { interpolate (start: [=11=], end: , by: by, nonlinearity: nonlinearity)}
}
给定默认的 by
和 nonlinearity
参数,上面的 returns 一个 mathOperation
for interpolate
。
在行动:
// Just add - only an example
1> func interpolate (start: Double, end: Double, by: Double, nonlinearity: (Double) -> Double) -> Double { return start + end }
6> func interpolateToMathOperation (by: Double, nonlinearity: @escaping (Double) -> Double) -> (Double, Double) -> Double {
7. return { interpolate (start: [=12=], end: , by: by, nonlinearity: nonlinearity)}
8. }
9> var mathOperation = interpolateToMathOperation (by: 0.25, nonlinearity: { [=12=] })
mathOperation: (Double, Double) -> Double = 0x00000001005ea670 $__lldb_expr15`partial apply forwarder for __lldb_expr_14.(interpolateToMathOperation (by : Swift.Double, nonlinearity : (Swift.Double) -> Swift.Double) -> (Swift.Double, Swift.Double) -> Swift.Double).(closure #1) at repl14.swift
10> mathOperation(1,2)
$R1: Double = 3
我对 Swift 中的函数存储和传递有点熟悉,但是我对该语言在这方面的行为有几个具体问题。
假设我们有一个变量函数 MathOperation:
var mathOperation: (Double, Double) -> Double
现在假设我们将其设置为函数 Subtract:
func subtract (minuend: Double, subtrahend: Double) -> Double {
return minuend - subtrahend
}
mathOperation = subtract
然后我们应该可以用
调用subtract
let result = mathOperation(3, 4.222)
但是,如果我们想传入一个比 mathOperation
声明要求的参数更多或顺序不同的参数怎么办?例如:
func divide (dividend: Double, divisor: Double, roundToInt: Bool = false) -> Double { ... }
如何将 mathOperation
设置为 divide
,从而忽略 roundToInt
?
此外,是否可以重新排列参数?假设我们在无法修改的库中有一个求幂函数:
func exponentiate (power: Double, base: Double) -> Double { ... }
在base之前有power是不常见的,假设使用mathOperation
的地方,我们需要像用(base: Double, power: Double)
声明的那样调用它。
有没有办法把mathOperation
设置成exponentiate
,这样调用的时候参数就反转了?
最后一个问题。假设我们有一个插值函数,我们想将 mathOperation
设置为:
func interpolate (start: Double, end: Double, by: Double, nonlinearity: (Double) -> Double) -> Double { ... }
有没有办法将 mathOperation
设置为 interpolate
以便
mathOperation (a, b)
结果
interpolate (start: a, end: b, by: 0.5, nonlinearity: { [=18=] })
如果其中任何一个是可能的,那么如果有人可以指导我找到对此进行解释的官方文档,那将是理想的。
对于您的插值案例(其他案例如下)只需定义以下内容:
mathOperation = { interpolate (start: [=10=], end: , by: 0.5, nonlinearity: { [=10=] })}
本质上,您将 interpolate
包装在一个闭包中,其中一些参数是固定的,例如本例中的 by
到 0.5
。 (这称为“partial application”)
您还可以将其归纳为如下内容:
func interpolateToMathOperation (by: Double, nonlinearity: @escaping (Double) -> Double) -> (Double, Double) -> Double {
return { interpolate (start: [=11=], end: , by: by, nonlinearity: nonlinearity)}
}
给定默认的 by
和 nonlinearity
参数,上面的 returns 一个 mathOperation
for interpolate
。
在行动:
// Just add - only an example
1> func interpolate (start: Double, end: Double, by: Double, nonlinearity: (Double) -> Double) -> Double { return start + end }
6> func interpolateToMathOperation (by: Double, nonlinearity: @escaping (Double) -> Double) -> (Double, Double) -> Double {
7. return { interpolate (start: [=12=], end: , by: by, nonlinearity: nonlinearity)}
8. }
9> var mathOperation = interpolateToMathOperation (by: 0.25, nonlinearity: { [=12=] })
mathOperation: (Double, Double) -> Double = 0x00000001005ea670 $__lldb_expr15`partial apply forwarder for __lldb_expr_14.(interpolateToMathOperation (by : Swift.Double, nonlinearity : (Swift.Double) -> Swift.Double) -> (Swift.Double, Swift.Double) -> Swift.Double).(closure #1) at repl14.swift
10> mathOperation(1,2)
$R1: Double = 3