Swift 中的柯里化 | Soledad
在使用一门新语言时,如果你没有进行思维上的转变的话,那么你就是落后于语言的。也就是说,你在用 Swift 写 OC 的代码。
最近身心俱疲,不如歇口气,停下来品一品 Swift,调节一下心情。
这次盯上的是 Swift 函数式编程的特性之一,柯里化。
柯里化
在维基百科中,是这样定义柯里化的:“In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument. ”
翻译过来,柯里化是数学和计算机科学中的一个概念,它是一种将一个接受 n 个参数的函数,转变成 n 个函数的序列,其中这 n 个函数每个都只接受单独的参数。用代码来表示,即:
1 2 3 4 5 6 7 | 将 func x(a: A, b: B, c: C) -> E 转变成 func x(a: A) -> (b: B) -> (c: C) -> E |
下面将从两个方面进行介绍柯里化。一种是普通函数的柯里化 (Currying Custom Functions),另一种是类名调用的柯里化 (Function Currying with Classes)。
普通函数的柯里化
我们一般实现加法的方式为
1 2 3 4 | func normalAdd(_ x1:Int,_ x2:Int) -> Int { return x1 + x2 } normalAdd(1, 2)// 值为 3 |
使用 curring 方法实现加法:
1 2 3 4 5 6 | func curryAdd(_ x1:Int) -> ((Int) -> Int)) { return { x2 in return x1 + x2 } } curryAdd(1)(2)// 值为 3 |
在第二个 currying 方法中,curryAdd(1) 返回的是 (Int) -> Int 类型。(我强烈建议读者也在 playground 中试一试)
类名调用的柯里化
还是通过例子来说明:
1 2 3 4 5 6 7 8 | class Car { var speed = 0 func accelerateBy(_ factor: Int) -> Int { speed += factor return speed } } let myCar = Car() |
在一般情况下,我们会这样调用 accelerateBy(_:) 函数:
myCar.accelarateBy(10)
然而,我们还有一种通过柯里化的方式来调用,而实际上,上述的通过实例调用实例方法也是转为下面的柯里化的方式来执行的。
Car.accelerateBy(myCar)(10)
在这里,Car.accelerateBy(myCar) 返回的也是一个 (Int) -> Int 类型。
柯里化有什么样的优点
在简单了解完柯里化之后,我们需要考虑的问题是,那我们为什么要用柯里化呢?换句话说,柯里化有什么样的优点呢?
在此,需要先了解一下 Swift 中的 Map,Filter 和 Reduce。关于 Map,我也写了一篇文章,在这里。
未完待续。