购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 理论背景:柯里化

在本章中,我们已经看到了用于定义接受两个参数的函数的两种方法。对大多数程序员来说,应该会觉得第一种风格更熟悉:

add1 函数接受两个整型参数并返回它们的和。然而在Swift中,我们对该函数的定义还可以有另一个版本:

这里的 add2 函数接受第一个参数 x 之后,返回一个 闭包 ,然后等待第二个参数 y 。这两个 add 函数的调用方法自然也是不同的:

在第一种方法中,我们将两个参数同时传递给 add1 ;而第二种方法则首先向函数传递第一个参数 1 ,然后将返回的函数应用到第二个参数 2 。两个版本是完全等价的:我们可以根据 add2 来定义 add1 ,反之亦然。

在Swift中,我们甚至可以省略 add2 函数的一个return关键字和返回类型中的某些括号,然后写为下面这样:

函数中的箭头 -> 向右结合。这也就是说,你可以将 A-> B-> C 理解为 A->(B-> C) 。然而在本书中,我们通常会为函数类型引入一个类型别名(像我们对 Region Filter 类型做的处理一样),或者是显式地写括号来提升代码的可读性。

add1 add2 的例子向我们展示了如何将一个接受多参数的函数变换为一系列只接受单个参数的函数,这个过程被称为 柯里化 (Currying),它得名于逻辑学家Haskell Curry;我们将 add2 称为 add1 的柯里化版本。

那么,为什么说柯里化很有趣呢?正如到现在我们在本书中所看到的,在一些情况下,你可能想要将函数作为参数传递给其他函数。如果我们有像 add1 一样 未柯里化 的函数,那么我们就必须用到它的 全部两个 参数来调用这个函数。然而,对于一个像 add2 一样被 柯里化 了的函数来说,我们有两个选择:可以使用一个 两个参数来调用。在本章中为了创建滤镜而定义的函数全部都已经被柯里化了——它们都接受一个附加的图像参数。按照柯里化风格来定义滤镜,我们可以很容易地使用 >>> 运算符将它们进行组合。假如我们用这些函数 未柯里化 的版本来构建滤镜,虽然依然可以写出相同的滤镜,但是这些滤镜的类型将根据它们所接受的参数不同而略有不同。这样一来,想要为这些不同类型的滤镜定义一个统一的组合运算符就要比现在困难得多了。 qmeER/un+HldCIqkcvVmXG98gjJAs1/t5rsU5gTcxbLX5ecbyBaWgUb8106J3Qr0

点击中间区域
呼出菜单
上一章
目录
下一章
×