浅谈 Swift 柯里化(Currying)
来源:互联网 发布:淘宝快递多久自动售货 编辑:程序博客网 时间:2024/05/21 13:16
在 Swifter中,第一章 就是 讲解 柯里化。这本书 真的是非常的不错,值得一看,同时,正如作者王巍所说,国内的 大量的流水线书籍真的没必要买。如果 你希望入门,去这里,如果 你想提高,我非常推荐这本书。当然 你也可以在这里找到它的内容。
继续说柯里化:
先理解柯里化:把接受多个参数的方法变换成接受第一个参数的方法,并且 返回接受余下的参数并返回结果的新方法。用数学的思维很好理解,一个函数 xy ,当 传入 y = 2,返回的 就是 2x。
写一个简单的例子。
func JustForExample(a:Int)(b:Int) -> Int{ return a + b }这个方法需要传入两个参数,但是我们没有写成 (a:Int,b:Int),而是分成了多个括号
func exampleUse() { let exampleAdd = JustForExample(3) //只传入第一个参数,返回一个函数,函数为 Int ->Int let result = exampleAdd(b:7)//传入 Int 返回 Int print(result) }这就是柯里化的简单应用,当然 柯里化 在 js 等 中 也是很常用的。
上面这段代码简单,但是下面这段代码 就不是很容易理解了。借鉴自:Ole Begemann
class BankAccount { var balance: Double = 0.0 func deposit(amount: Double) { balance += amount } }定义了一个class,其中有一个方法 deposit(Double),
正常使用:
let account = BankAccount() account.deposit(100) // balance = now利用柯里化我们可以这么写:
let depositor = BankAccount.deposit depositor(account)(100) // balance = 200
仔细观察,我们发现depositor 没有实例化一个BankAccout对象,而是直接引用他的deposit方法,这就类似于C语言的函数指针。然后通过 给depositor传入一个实例化对象,返回一个 完整的deposit(Double)函数,然后 传入一个Double,返回空。
拆开depositor我们 可以这么写:
let depositor: BankAccount -> (Double) -> ()分成两部分来看,第一部分:
BankAccount -> (Double) 传入一个 BankAccount实例,返回一个需要传入Double的Function,第二部分:
(Double) -> () 传入一个Double,返回 空,你应该理解为对 deposit() 的签名。然后是 原文照着这个思路 ,借助柯里化 ,对target-acton的安全的改造。(因为 Swift的Selector 只能以字符串生成,面临难以重构的问题,并且无法再编译期间检查)。
以下是代码:
/// 目标事件协议protocol TargetAction { func performAction() }/** OC中的委托 事件包装结构,这里是泛型,这里表示传入的数据类型可以是AnyObject 这个方法遵循TargetAction协议来处理事件 */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 currying{ var actions = [ControlEvent :TargetAction]() func setTarget<T:AnyObject>(target: T,action: (T) -> () -> (),controlEvent:ControlEvent){ actions[controlEvent] = TargetActionWrapper(target:target,action:action) print(T) print(action) } /// 移除 func removeTargetForControlEvent(controlEvent:ControlEvent){ actions[controlEvent] = nil } /// 执行 func performActionForControlEvent(controlEvent:ControlEvent){ actions[controlEvent]?.performAction() } }使用:
class ViewController: UIViewController { let button = currying() override func viewDidLoad() { super.viewDidLoad() button.setTarget(self, action: ViewController.onButtonTap, controlEvent: .TouchUpInside) // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func onButtonTap(){ } func exampleUse() { let exampleAdd = JustForExample(3) //只传入第一个参数,返回一个函数,函数为 Int ->Int let result = exampleAdd(b:7)//传入 Int 返回 Int print(result) } func JustForExample(a:Int)(b:Int) -> Int{ return a + b } }写在最后:
不知道为什么,在你写上面的example的时候,会告诉你,Swift 会 在不久移除 柯里化 这种 申明语法,推荐使用简单的多参数设计。当然, 即使 要去掉,这种 有趣的知识, 也是值得学习的。
1 0
- 浅谈 Swift 柯里化(Currying)
- Swift柯里化(Currying)
- Swift柯里化(Currying)
- Swift柯里化(Currying)
- Swift 柯里化(Currying)
- Currying-柯里化[Swift笔记]
- Swift 柯里化(Currying)
- Swift函数柯里化(Currying)简谈
- swift 学习笔记之在柯里化(Currying)
- 柯里化(Currying)
- 函数柯里化(Currying)
- Swift 柯里化(currying)和反柯里化(uncurrying)
- Scala 函数柯里化(Currying)
- JavaScript中的柯里化(currying)
- 函数柯里化function currying
- Currying
- swift浅谈(一)
- currying in javascript-js柯里化
- 序列化与反序列化
- 苹果iPhone 7要来了 手里的旧6/6s怎么处理最划算
- oracle中拼接sql过长的解决方法
- codeforces 703 A. Mishka and Game (水)
- JavaScript DOM操作记录
- 浅谈 Swift 柯里化(Currying)
- bzoj 4565: [Haoi2016]字符合并 (字符串dp)
- OC_11_2协议
- java监听器
- Robotium学习(六)-运行错误的解决方法
- Ext JS Data Package
- TESTNG组测试
- NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END
- unity中把材质截图当材质的matcap材质