美文网首页
Swift-Currying(柯里化)

Swift-Currying(柯里化)

作者: Style_月月 | 来源:发表于2020-07-14 00:10 被阅读0次

1、什么是柯里化?

柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数切返回结果的新函数的技术

用数学理解就是:一个函数求xy,当传入y=2时,返回的就是2x

2、简单示例

例如:实现一个函数,输入的是任一整数,输出要返回输入的整数+2

一般的写法是

func addTwo(_ a : Int)->Int{
        return a+2
    }
image.gif

上面这种写法就只是简单的可以实现这个函数,并没有进行优化,且不通用,里面的+2直接固定写死了,如果要实现+4/+6/+8,不能每次都去重新定义一个函数,我们需要定义一个通用的函数,所以需要做如下改进,主要利用的是swift的currying技术

func addTwo(_ a : Int)->(Int)->Int{
        return {b in
            return a+b
        }
    }
image.gif

上面的函数可以简化成

func addTwo(_ a : Int)->(Int)->Int{
        return {b in a+b }
    }
image.gif

还可以更通用一些,将参数定义为泛型

    //两个参数的泛型
    func curry<A, B>(_ function:@escaping (A)->B)->(A)->B{
        return {a in function(a)}
    }
    //三个参数的泛型
    func curry<A, B, C>(_ function:@escaping (A, B)->C)->(A)->(B)->C{
        return {a in {b in function(a,b)}}
    }
    //四个参数的泛型
    func curry<A, B, C, D>(_ function:@escaping (A, B, C)->D)->(A)->(B)->(C)->D{
        return {a in {b in {c in function(a, b, c)}}}
    }

    //currying调用
    func addTwo(_ a : Int, _ b : Int)->Int{
        return a+b
    }

    let result = curry(addTwo)(1)(2) //打印的结果为3
image.gif

3、项目中的实际应用

主要应用在需要传多个参数的函数,

1)例如:假设有这样一个需求,我需要记录某个系统的日志,日志需要包含以下几个要素:操作人的名字name,时间time,日志类型type和日志内容msg。

    func curry<A, B, C, D, E>(_ function:@escaping (A, B, C, D)->E)->(A)->(B)->(C)->(D)->E{
        return {a in {b in {c in {d in function(a, b, c, d)}}}}
    }

    func createLogInfo(_ name : String, _ time : String, _ type : String, _ msg : String)->String{
        return "name : \(name)\n" + "type : \(type)\n" + ("message : \(msg)\n" + "time: \(time)    ")
    }

    //调用
    let createLogInfoResult = curry(createLogInfo)("functionName")("today")("Error")("somethingWrong")

输出结果:
name : functionName
type : Error
message : somethingWrong
time: today
image.gif

2)封装target-action,对其安全的改造

原因:由于swift的selector智能是字符串生成,面临难以重构的问题,并且无法在编译期间检查

改造的步骤:

(1)定义一个目标事件协议

//目标事件协议
protocol TargetAction {
    func performAction()
}
image.gif

(2)定义一个类,遵循(1)中的协议来处理事件

/**

 OC中的委托

 事件包装结构,这里是泛型,这里表示传入的数据类型可以是AnyObject

 这个方法遵循TargetAction协议来处理事件

 */

struct TargetActionWrapper<T: AnyObject>:TargetAction {

    weak var target : T?

    //柯里化
    let action : (T) -> () -> ()

    func performAction() {
        if let t = target {
            action(t)()
        }
    }
}
image.gif

(3)枚举事件的类型

//枚举
enum ControlEvent{
    case TouchUpInside
    case ValueChanged
    //...
}
image.gif

(4)示例

//示例
class currying{
    var actions = [ControlEvent : TargetAction]()
    func setTarget<T: AnyObject>(_ target : T, _ action : @escaping (T)->()->(), _ controlEvent : ControlEvent){
        actions[controlEvent] = TargetActionWrapper(target: target, action: action)
        print("T \(T.self)")
        print("action \(action)")
    }

    //移除
    func removeTargetForControlEvent(_ controlEvent : ControlEvent){
        actions[controlEvent] = nil
    }

    //执行
    func performActionForControlEvent(_ controlEvent : ControlEvent){
        actions[controlEvent]?.performAction()
    }
}
image.gif

(5)在项目中的实际使用

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        currying().setTarget(self, ViewController.btnclick, .TouchUpInside)

    }

     func btnclick(){
        print("点击了")
    }
}
image.gif

相关文章

  • Swift-Currying(柯里化)

    1、什么是柯里化? 柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受...

  • 手写简单.bind()实现

    手写一个实现柯里化的.bind() 柯里化:《函数柯里化小结》柯里化:前端开发者进阶之函数柯里化Currying ...

  • 函数式编程(三)—— 柯里化

    柯里化Lodash中的柯里化 —— curry()案例柯里化原理模拟柯里化总结 【函数式编程总体设计】 之前讲了函...

  • [译]JavaScript中的函数柯里化

    原文 Currying in JS 函数柯里化 函数柯里化以Haskell Brooks Curry命名,柯里化是...

  • 简单理解JavaScript中的柯里化和反柯里化

    简单理解JavaScript中的柯里化和反柯里化 前言 本文旨在让大家简单理解柯里化和反柯里化,这里不做深入探究,...

  • 简单理解JavaScript中的柯里化和反柯里化

    简单理解JavaScript中的柯里化和反柯里化 前言 本文旨在让大家简单理解柯里化和反柯里化,这里不做深入探究,...

  • js柯里化

    标签: js柯里化 js柯里化 柯里化是什么在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成...

  • 柯里化和反柯里化

    一、柯里化 定义函数柯里化就是把一个函数中的一些可以固定的参数固定后生成新的函数比如一个函数: 现在有一个需求:就...

  • swift 柯里化

    swift 柯里化 柯里化 1、什么是柯里化? 柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一...

  • JS函数式编程之柯里化

    JS函数式编程之柯里化 为什么要了解柯里化 柯里化是函数式编程必须要使用的. 这里我们就先介绍下什么是柯里化, 然...

网友评论

      本文标题:Swift-Currying(柯里化)

      本文链接:https://www.haomeiwen.com/subject/vqmthktx.html