Swift柯里化(Currying)
什么是Currying, Currying将一个多参数方法分解成只有一个参数的方法,这个方法返回的不是一个具体值,而是返回余下方法的"片段"。
举个例子:
func addValue(originValue:Int)(inputVlue:Int) ->Int{ //这种两个括号就是currying函数的写法
returnoriginValue + inputVlue
}
let addValue10 =addValue(10)//这一步不会返回具体值而是返回余下函数 (在playground中不难看出)
从上图可以看出在playground中addValue10返回了一个函数 而不是具体的值,addValue10代表addValue10(inputVlue:Int) 对应后面的参数函数.
addValue10(inputVlue:10) //到这里才会返回具体的值 == 20
我们还可以在后边添加更多参数 比如
func addValue(originValue:Int)(inputVlue:Int)(inputVlue2:Int) ->Int{
returnoriginValue + inputVlue + inputVlue2
}
具体运行效果可以自己测试。
下面我们可以看看下面的例子:
class BankAccount {
var balance:Double=0.0
func deposit(amount:Double) {
balance+= amount
}
}
let account =BankAccount()
account.deposit(100)// 100
上面是调用实例方法的方式,但是我们还可以通过如下方式调用:
let depositor=BankAccount.deposit
depositor(account)(100)// balance is now 200
实例方法其实就是类方法以对象为第一个参数的currying化过程。
deposit方法 的形式为:
let depositor:BankAccount->(Double)->()
详见这篇博客:Instance Methods are Curried Functions in Swift
最后附上如何用Currying实现Target-Action
protocol TargetAction {
func performAction()
}
struct TargetActionWrapper :TargetAction{
weak var target:T?
let action: (T) -> () -> ()
func performAction() -> () {
if let t =target{
action(t)()
}
}
}
enumControlEvent {
caseTouchUpInside
caseValueChanged
// ...
}
classControl {
varactions = [ControlEvent:TargetAction]()
funcsetTarget(target:T, action: (T) -> () -> (), controlEvent:ControlEvent) {
actions[controlEvent] =TargetActionWrapper(target: target, action: action)
}
func removeTargetForControlEvent(controlEvent:ControlEvent) {
actions[controlEvent] =nil
}
func performActionForControlEvent(controlEvent:ControlEvent) {
actions[controlEvent]?.performAction()
}
}
classMyViewController {
letbutton =Control()
funcviewDidLoad() {
button.setTarget(self, action:MyViewController.onButtonTap, controlEvent: .TouchUpInside)
}
funconButtonTap() {
println("Button was tapped")
}
}