swift新元素
柯里化(Currying)
Swift 里可以將方法進(jìn)行柯里化(Currying),這是也就是把接受多個(gè)參數(shù)的方法進(jìn)行一些變形,使其更加靈活的方法。函數(shù)式的編程思想貫穿于Swift中,而函數(shù)的柯里化真是這門語言函數(shù)式特點(diǎn)的重要表現(xiàn)。
舉個(gè)例子,下面的函數(shù)簡單地將輸入的數(shù)字加1:
func addTo(_ adder: Int) -> (Int) -> Int {
return {
num in
return num + adder
}
}
有了addTo,我們現(xiàn)在就能輕易寫出像是 addOne 或者 addTwo 這樣的函數(shù)了:
let addTwo = addTo(2) // addTwo: Int -> Int
let result = addTwo(6) // result = 8
再舉一個(gè)例子,我們可以創(chuàng)建一個(gè)比較大小的函數(shù)
func greaterThan(_ comparer: Int) -> (Int) -> Bool {
return { $0 > comparer }
}
let greaterThan10 = greaterThan(10);
greaterThan10(13) // => true
greaterThan10(9). // => false
舉一個(gè)實(shí)際應(yīng)用時(shí)候的例子,在Selector一節(jié)中,我們提到了在Swift中 Selector 只能使用字符串在生成。這面臨一個(gè)很嚴(yán)重的問題,就是難以重構(gòu),并且無法在編譯期間進(jìn)行檢查,其實(shí)這是十分危險(xiǎn)的行為。但是 target-action 又是 Cocoa 中如此重要的一種設(shè)計(jì)模式,無論如何我們都想安全地使用的話,應(yīng)該怎么辦呢?一種可能的解決方式就是利用方法的柯里化。Ole Begemann在這篇帖子里提到了一種很好封裝,這為我們?nèi)绾谓柚吕锘?,安全地改造和利?target-action提供了不少思路。
protocol TargetAction {
func performAction()
}
struct TargetActionWrapper <T: AnyObject>:
TargetAction {
weak var target: T?
let action: (T) -> () -> ()
func performAction() -> () {
if let t = target {
action(t)()
}
}
}
enum ControlEvent {
case TouchUpInside
case ValueChanged
// ...
}
class Control
var actions = [ControlEvent: TargetAction]()
func setTarget<T: AnyObject>(target: T, action:@escaping (T ) -> () -> (),controlEvent: ControlEvent) {
actions[controlEvent] = TargetActionWrapper {
target: target,action: action)
}
func removeTargetForControlEvent(controlEvent: ControlEvent) {
actions[controlEvent] = nil
}
func performActionForControlEvent(controlEvent: ControlEvent) {
actions[controlEvent]?.performAction()
}
}