本篇并没有花费多大的精力整理查阅,仅仅是将Swift 必备 Tips书中的内容,写给大家看一下,对大家了解Swfit 柯里化是有比较大的帮助的!
Swift里可以将方法进行柯里化,也就是把接受多个参数的方法进行一些变形,使其更加灵活的方法。函数式的编程思想贯穿于Swift,而函数的柯里化正是Swift 语言函数式特点的重要表现。
举个例子,下面的函数简单地将输入的数字加1:
func addOne(num: Int) -> Int {
return num + 1
}
这个函数所表达的内容非常有限,如果我们之后还需要一个将数字加2,或者加3的函数,可能不类似地去定义返回为num + 2 或者num + 3的版本。有没有更通用的方法呢?
我们其实可以定义一个通用的函数,它将接受需要与输入数字本身,然后进行操作:
func addTo(_ adder: Int) -> (Int) -> Int {
return { num in
return num + adder
}
}
有了addTo,我们现在就能轻易写出像是addOne或者addTwo这样的函数啦:
let addTwo = addTo(2) //addTwo: (Int) -> Intlet result = addTwo(6)//result = 8
再举一个例子,我们可以创建一个比较大小的函数:
func greaterThan(_ comparer: Int) -> (Int) -> Bool {
return {$0 > comparer}
}
let greaterThan10 = greaterThan(10)
greaterThan10(13)// => true
greaterThan10(8)// => false
柯里化是一种量产相似方法的好办法,可以通过柯里化一个方法模板来避免写出很多重复代码,也方便了今后维护。
拓展:
举一个实际运用的例子,在Swift中Selector只能使用字符串生成。这面临着一个很严重的问题,就是难以重构,并且无法再编译期间进行检查,这是非常危险的行为。但是Target-Action又是Cocoa如此重要的一项重要的设计模式,我们也可以采取利用方法的柯里化。
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){
action[controlEvent] = TargetActionWrapper(target: target, action: action)
}
func removeTargetForControlEvent(controlEvent: ControlEvent) {
actions[controlEvent] = nil
}
func performActionForControlEvent(controlEvent: ControlEvent) {
actions[controlEvent]?.performAction()
}
}
使用方法:
class MyViewController {
let button = Control()
func viewDidLoad() {
button.setTarget(self, action: MyViewController.onButtonTap, controlEvent: .touchUpInside)
}
func onButtonTap() {
print("Button was tapped")
}
}
上面就是柯里化的相关知识,大家可以使用起来撒,个人推荐Swift 必备 Tips这本书,扎实的基础功能永远是可靠的。