标签:返回结果 调用 数据 let 系统 type 完数 执行 ref
柯里化(Currying),又称部分求值(Partial Evaluation),是一种函数式编程思想,就是把接受多个参数的函数转换成接收一个单一参数(最初函数的第一个参数)的函数,并且返回一个接受余下参数的新函数技术。
uncurried: 普通函数
// 接收多个参数的函数(与类相关的函数,统称为方法,但是这里就直接说函数了,方便理解)
func add(a: Int, b: Int, c: Int) -> Int {
print("\(a) + \(b) + \(c)")
return a + b + c
}
curried: 柯里化函数
// 柯里化函数,Swift 3.0 之前支持这样的语法,可以直接写
func addCur(a: Int)(b: Int)(c: Int) -> Int {
println("\(a) + \(b) + \(c)")
return a + b + c
}
定义柯里化函数
func function name (parameters)(parameters) -> return type {
statements
}
uncurried: 普通函数
class Currying {
// 接收多个参数的函数
func add(a: Int, b: Int, c: Int) -> Int {
print("\(a) + \(b) + \(c)")
return a + b + c
}
}
系统自带的柯里化函数
class Currying {
func addCur(a: Int)(b: Int)(c: Int) -> Int {
print("\(a) + \(b) + \(c)")
return a + b + c
}
}
手动实现柯里化函数
把上面的函数转换为柯里化函数,首先转成接收第一个参数 a
,并且返回接收余下第一个参数 b
的新函数(采用闭包).
这里为什么能使用参数 a、b、c
?
a、b、c
都在闭包中。class Currying {
// (a: Int) : 参数
// (b: Int) -> (c: Int) -> Int : 函数返回值(一个接收参数 b 的函数,并且这个函数又返回一个接收参数 c,
// 返回值为 Int 类型的函数)
// 定义一个接收参数 a,并且返回一个接收参数 b 的函数,并且这个函数又返回一个接收参数 c,返回值为 Int 类型的函数。
func add(a: Int) -> (b: Int) -> (c: Int) -> Int {
// 返回一个接收参数 b 的函数,并且这个函数又返回一个接收参数 c,返回值为 Int 类型的函数
return { (b:Int) -> (c: Int) -> Int in
// 返回一个接收余下第一个参数 c,并且返回结果为 Int 类型的函数
return { (c: Int) -> Int in
return a + b + c;
}
}
}
}
创建柯里化类的实例
var curryInstance = Currying()
手动实现的柯里化函数调用
var result: Int = curryInstance.add(a: 10)(b: 20)(c: 30)
[[Person alloc] init]
,这种写法应该都见过吧,就是一下发送了两个消息,alloc
返回一个实例,再用实例调用 init
初始化,上面也是一样,一下调用多个函数,每次调用都会返回一个函数,然后再次调用这个返回的函数。手动实现的柯里化函数拆解调用
curryInstance.add(a: 10)
调用一个接收参数 a
,并且返回一个接收参数 b
的函数,并且这个函数又返回一个接收参数 c
,返回值为 Int
类型的函数。
// functionB: 一个接收参数 b 的函数,并且这个函数又返回一个接收参数 c,返回值为 Int 类型的函数
let functionB = curryInstance.add(a: 10)
functionB(b: 20)
调用一个接收参数 b
的函数,并且这个函数又返回一个接收参数 c
,返回值为 Int
类型的函数。
// functionC: 一个接收参数 c,返回值为 Int 类型的函数
let functionC = functionB(b: 20)
functionC(c: 30)
调用一个接收参数 c
,返回值为 Int
类型的函数。
// result: 函数的返回值
var result: Int = functionC(c: 30);
系统的柯里化函数调用
var result: Int = curryInstance.addCur(a: 10)(b: 20)(c: 30)
系统的柯里化函数拆解调用
curryInstance.addCur(a: 10)
调用一个接收参数 a
,并且返回一个接收参数 b
的函数,并且这个函数又返回一个接收参数 c
,返回值为 Int
类型的函数。
// Swift是强类型语言,这里没有报错,说明调用系统柯里化函数返回的类型和手动的 functionB 类型一致
// functionB: 一个接收参数 b 的函数,并且这个函数又返回一个接收参数 c,返回值为 Int 类型的函数
functionB = curryInstance.addCur(a: 10)
functionB(b: 20)
调用一个接收参数 b
的函数,并且这个函数又返回一个接收参数 c
,返回值为 Int
类型的函数。
// functionC: 一个接收参数c,返回值为Int类型的函数
functionC = functionB(b: 20)
functionC(c: 30)
调用一个接收参数 c
,返回值为 Int
类型的函数。
// result: 函数的返回值
result = functionC(c: 30)
// 打印 60,60,60 说明手动实现的柯里化函数,和系统的一样。
print("\(r), \(res), \(result)")
必须按照参数的定义顺序来调用柯里化函数,否则就会报错。
柯里化函数的函数体只会执行一次,只会在调用完最后一个参数的时候执行柯里化函数体。
以下调用 functionC(c: 30)
才会执行函数体,这个可以自己断点调试。
// curried: 柯里化函数
func addCur(a: Int)(b: Int)(c: Int) -> Int {
println("\(a) + \(b) + \(c)")
return a + b + c
}
// 创建柯里化类的实例
var curryInstance = Currying()
// 不会执行柯里化函数体
functionB = curryInstance.addCur(a: 10)
// 不会执行柯里化函数体
functionC = functionB(b: 20)
// 执行柯里化函数体
result = functionC(c: 30)
这里就需要了解函数式编程思想了,柯里化函数就是运用了函数式编程思想,推荐看这篇文章函数式编程初探。
特点
好处
实用性一:复用性
需求 1:地图类产品,很多界面都有相同的功能模块,比如搜索框。
实用性二:延迟性
柯里化函数代码需要前面的方法调用完成之后,才会来到柯里化函数代码中。
需求 2:阅读类产品,一个界面的显示,依赖于数据,需要加载完数据之后,才能判断界面显示。
举例说明
// 组合接口
// 为什么要定义接口,为了程序的扩展性,以后只需要在接口中添加对应的组合方法就好了。
protocol CombineUI {
func combine(top: () -> ())(bottom: () -> ())()
}
// 定义一个界面类,遵守组合接口
class UI: CombineUI {
func combine(top: () -> ())(bottom: () -> ())() {
// 搭建顶部
top()
// 搭建底部
bottom()
}
}
Swift 中实例方法的柯里化调用
示例结构体
struct Example {
var internalStr = ""
func combine(externalStr: String) {
print(internalStr + " " + externalStr)
}
}
调用实例方法的常用格式
let example = Example(internalStr: "hello")
example.combine(externalStr: "word") // hello word
调用实例方法的柯里化格式
let example = Example(internalStr: "hello")
Example.combine(example)(externalStr: "word") // hello word
标签:返回结果 调用 数据 let 系统 type 完数 执行 ref
原文地址:https://www.cnblogs.com/QianChia/p/8876174.html