Swift 中的高阶函数;一个你可能听说过的术语,也许你使用过其中的一些或看到它们被使用,但你真的知道什么是高阶函数吗?
这篇文章致力于解释什么是高阶函数,以及它与普通函数的区别。在这里,您不仅会找到答案,还会看到如何实现自己的自定义高阶函数。后续文章将演示 Swift 中各种常用和众所周知的内置高阶函数。
当涉及到高阶函数时,只有一种想法需要理解。它们是接受其他函数作为参数的函数,或者它们返回一个函数作为结果。闭包也是如此;毕竟,闭包是一个无名的函数。所以,再一次……
高阶函数是接受其他函数或闭包作为参数,或返回一个函数或闭包作为其结果的函数。
这听起来不错,但它在实践中的真正含义是什么?要体验一下,请在 Xcode 中打开一个 Playground 并跟随。无论是否可能创建您自己的高阶函数,接下来的示例都将帮助您完全理解这些函数是什么。
首先,假设我们有以下枚举表示四种基本数学运算:
enum MathOperation {
case addition, subtraction, multiplication, division
}
现在,假设我们要实现一个只做一件事的函数:
根据MathOperation我们将提供给它的值,它将返回一个函数,该函数将在两个操作数之间执行实际的数学运算。
为简单起见,我们同意只处理 Double 值。该函数的定义如下:
func math(operation: MathOperation) -> (Double, Double) -> Double? {
}
查看返回值;(Double, Double) -> Double?. 它是一个没有名字的函数的声明。我们以完全类似的方式声明闭包,不是吗?参数值匹配两个 Double 类型的操作数,而结果也是一个 Double 值。它标有 ? 符号作为可选,因此在除法为零的情况下,程序不会崩溃。
现在让我们为上述函数添加一些内容,从将计算每个操作的结果的四个函数的实现开始。请注意,所有新函数都在math(operation:)函数内部定义-是的,我们可以这样做-:
func math(operation: MathOperation) -> (Double, Double) -> Double? {
func addition(_ val1: Double, _ val2: Double) -> Double { val1 + val2 }
func subtraction(_ val1: Double, _ val2: Double) -> Double { val1 - val2 }
func multiplication(_ val1: Double, _ val2: Double) -> Double { val1 * val2 }
func division(_ val1: Double, _ val2: Double) -> Double? {val2 != 0 ? val1/val2 : nil}
接下来,我们将math(operation:)根据operation参数值从 返回正确的函数:
func math(operation: MathOperation) -> (Double, Double) -> Double? {
func addition(_ val1: Double, _ val2: Double) -> Double { val1 + val2 }
func subtraction(_ val1: Double, _ val2: Double) -> Double { val1 - val2 }
func multiplication(_ val1: Double, _ val2: Double) -> Double { val1 * val2 }
func division(_ val1: Double, _ val2: Double) -> Double? {val2 != 0 ? val1/val2 : nil}
switch operation {
case .addition: return addition(_:_:)
case .subtraction: return subtraction(_:_:)
case .multiplication: return multiplication(_:_:)
case .division: return division(_:_:)
}
}
以上是高阶函数!它返回另一个函数作为结果。
我们现在可以按如下方式使用它:
let num1: Double = 5.5
let num2: Double = 10.5
var operation = math(operation: .addition)
print(operation(num1, num2)!)
operation = math(operation: .multiplication)
print(operation(num1, num2)!)
第一次math(operation:)调用时,它返回addition(_:_:)函数。第二次返回multiplication(_:_:)函数,由提供的参数指定。在两个给定数字之间执行实际数学运算后,打印命令将分别显示值 16.0 和 57.75。
现在让我们实现一个函数,它接受另一个函数作为参数,而不是返回一个作为其结果的函数。我将从执行基本计算的四个相同的数学函数开始:
func addition(_ val1: Double, _ val2: Double) -> Double { val1 + val2 }
func subtraction(_ val1: Double, _ val2: Double) -> Double { val1 - val2 }
func multiplication(_ val1: Double, _ val2: Double) -> Double { val1 * val2 }
func division(_ val1: Double, _ val2: Double) -> Double? { val2 != 0 ? val1/val2 : nil }
有了上面的授权,这里是新函数的定义:
func performOperation(val1: Double,
val2: Double,
operation: (Double, Double) -> Double) -> Double? {
}
前两个参数值是将用于计算结果的两个操作数。第三个参数值,也是这里最有趣的部分,是一个函数;它需要两个 Double 类型的参数,返回一个可选的 Double 结果。
在它的主体内,只有一行将调用operation传递前两个参数值作为参数的函数:
func performOperation(val1: Double,
val2: Double,
operation: (Double, Double) -> Double) -> Double? {
operation(val1, val2)
}
operation将匹配的实际函数取决于我们将作为参数提供的函数。例如,要执行乘法,我们可以使用我们想要相乘的两个值调用上面的函数,加上执行乘法的函数:
var result = performOperation(val1: num1, val2: num2, operation: multiplication(_:_:))
print(result!)
要执行减法:
result = performOperation(val1: num1, val2: num2, operation: subtraction(_:_:))
print(result!)
在最后两个示例中,我们提供了一个命名函数作为参数。但是,这不是强制性的。我们可以使用闭包代替。以下示例演示了如何将闭包作为参数传递给演示高阶函数。在它的主体中,我们计算并返回两个给定值的平均值:
result = performOperation(val1: num1, val2: num2, operation: { val1, val2 in
(num1 + num2)/2
})
print(result!)
现在您知道高阶函数术语的含义,以及它们与称为一阶函数的普通函数相比的区别。尽管提供的示例非常简单,但它们仍然足以帮助您了解该主题。
在接下来的文章中,我将展示 Swift 中提供的某些内置高阶函数是如何工作的,以及你可以用它们做什么。我将从map,compactMap和flatMap函数开始,然后我将继续讨论其他一些。所以,请继续关注!