Swift开发实战

Swift柯里化(Currying)

2015-09-10  本文已影响827人  sprint

什么是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")

}

}

上一篇下一篇

猜你喜欢

热点阅读