iOS函数式编程和链式编程的实现

首先来看下什么是函数式编程,举个例子:

[view mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.bottom.left.right.equalTo(self.view);
}];

这里的

make.top.bottom.left.right.equalTo(self.view);

就是典型的函数式编程。

那么什么是链式编程呢,这种.top.bottom.left.right.equalTo(self.view)通过"."语法,将需要执行的代码连续的书写,就叫做链式编程,它使得代码简单易懂。
而这种.equalTo(self.view)通过"()"来实现函数的调用,就是函数式编程。

比如我们要实现一个加减乘除的函数式编程,用来计算(2+3-1)*3/4的结果:
先看下最后实现的效果

float result = self.add(2).add(3).minus(1).multiply(3).divide(4).giveMeResult;

现在我们开从最简单的开始写起:

第一种方法:

@interface ViewController : UIViewController
@property (nonatomic,assign) float tmp;
- (void)add:(float)value;
- (void)minus:(float)value;
- (void)multiply:(float)value;
- (void)divide:(float)value;
- (float)giveMeResult;
@end

实现上述方法

- (void)add:(float)value
{
    _tmp += value;
}
- (void)minus:(float)value
{
    _tmp -= value;
}
- (void)multiply:(float)value
{
    _tmp *= value;
}
- (void)divide:(float)value
{
    _tmp /= value;
}
- (float)giveMeResult
{
    return _tmp;
}

那么用这种写法,我们调用的话就是这样

[self add:2];
[self add:3];
[self minus:1];
[self multiply:3];
[self divide:4];
float result = [self giveMeResult];

emmmmm,也还看的过去吧,接下来我们稍微改造下:

第二种方法:

@interface ViewController : UIViewController
@property (nonatomic,assign) float tmp;
- (float)add:(float)value;
- (float)minus:(float)value;
- (float)multiply:(float)value;
- (float)divide:(float)value;
- (float)giveMeResult;
@end

实现上述方法

- (float)add:(float)value
{
    _tmp += value;
    return _tmp;
}
- (float)minus:(float)value
{
    _tmp -= value;
    return _tmp;
}
- (float)multiply:(float)value
{
    _tmp *= value;
    return _tmp;
}
- (float)divide:(float)value
{
    _tmp /= value;
    return _tmp;
}
- (float)giveMeResult
{
    return _tmp;
}

那么用这种写法,我们调用的话就是这样

float result = ([self add:2] + [self add:3] + [self minus:1])*[self multiply:3]/[self divide:4];

2019-04-22更新 多谢No_00指出,这里如果直接打印result结果为44,因为[self add:2]之后,结果为2,然后[self add:3],结果为_tmp+3=5,以此类推result=(2+5+4)*12/3也就是44。
当然,如No_00所说,这里的返回值可以写成return self,这样的话,最终就可以写成((((self.add(2)).add(3)).minus(1)).multiply(3)).divide(4),更趋近于函数式编程。为了循序渐进,所以本文采用四步法一步一步进行改造,方便理解。

哟,看起来初见端倪了,那么接下来我们就用block来实现"()"的调用方法,这次我们就不用上面的主动传参的方法了,而是放在block内部

第三种方法:

@interface ViewController : UIViewController
- (void (^)(float))add;
- (void (^)(float))minus;
- (void (^)(float))multiply;
- (void (^)(float))divide;
- (float)giveMeResult;
- (void)initUI;
@end
- (void (^)(float))add
{
    __weak typeof(self) wself = self;
    void (^result)(float) = ^(float value){
        wself.tmp += value;
    };
    return result;
}
- (void (^)(float))minus
{
    __weak typeof(self) wself = self;
    void (^result)(float) = ^(float value){
        wself.tmp -= value;
    };
    return result;
}
- (void (^)(float))multiply
{
    __weak typeof(self) wself = self;
    void (^result)(float) = ^(float value){
        wself.tmp *= value;
    };
    return result;
}
- (void (^)(float))divide
{
    __weak typeof(self) wself = self;
    void (^result)(float) = ^(float value){
        wself.tmp /= value;
    };
    return result;
}
- (float)giveMeResult
{
    return self.tmp;
}

我们来分析一下,这里所有的方法都返回的是一个block,请眼尖的同学不要拿- (float)giveMeResult跟我抬杠啊,你个杠精。当我们调用[self add]的时候,返回的是一个block,我们假定是这样

void (^AddResult)(float) = [self add];

那么如何执行这个block呢?聪明的你肯定知道

AddResult();

好,由于这是一个带参的block,那么我们传进去参数

AddResult(1);

但是,搞来搞去不是还要带上"[]"这个累赘吗?是啊,真的很蛋疼,但是大家想一下我们的"."语法的本质是什么,就是函数的隐式调用,我可以[self add],我也可以self.add!

什么,你不信?我多年的百度、谷歌、github经验能骗你?

好了,我们来实现下开始的计算:

self.add(2);
self.add(3);
self.minus(1);
self.multiply(3);
self.divide(4);
float result = self.giveMeResult;/*好吧,杠精有意见,看着不舒服,不这样写了,这位杠精朋友放学先别走,咱们谈谈人生,聊聊理想*/
float result = [self giveMeResult];

不错不错,基本上已经可以了,但是怎么能把这些实现串起来呢,跟着我的思路走:

self.add原本返回的是一个block,而self.add(2)返回的是void,如果我们能让他返回self,那么就可以使用这个返回值继续add(3)等其他操作了,沿着这个思路,我们进行最终的改造

退下,我要开始装逼了

第四种写法

@interface ViewController : UIViewController
- (ViewController *(^)(float))add;
- (ViewController *(^)(float))minus;
- (ViewController *(^)(float))multiply;
- (ViewController *(^)(float))divide;
- (float)giveMeResult;
@end

实现方法

- (ViewController *(^)(float))add
{
    __weak typeof(self) wself = self;
    ViewController *(^result)(float) = ^(float value){
        wself.tmp += value;
        return self;
    };
    return result;
}
- (ViewController *(^)(float))minus
{
    __weak typeof(self) wself = self;
    ViewController *(^result)(float) = ^(float value){
        wself.tmp -= value;
        return self;
    };
    return result;
}
- (ViewController *(^)(float))multiply
{
    __weak typeof(self) wself = self;
    ViewController *(^result)(float) = ^(float value){
        wself.tmp *= value;
        return self;
    };
    return result;
}
- (ViewController *(^)(float))divide
{
    __weak typeof(self) wself = self;
    ViewController *(^result)(float) = ^(float value){
        wself.tmp /= value;
        return self;
    };
    return result;
}
- (float)giveMeResult{
    return self.tmp;
}

好了,大功告成,多谢大家的观看。


image

还不懂?艾玛,行吧,我就多说几句。

上面已经解释过了,当我们调用[self add]或者self.add的时候返回的是一个block,如果我们要执行这个block的话,需要self.add(1),执行了block的话,返回值就是block返回的结果(艾玛,有点绕嘴呢)。
我们拆分来看这个函数

- (ViewController *(^)(float))add
{
    __weak typeof(self) wself = self;
    ViewController *(^result)(float) = ^(float value){
        wself.tmp += value;
        return self;
    };
    return result;
}

函数add的返回值是一个block,block的返回值是一个ViewController,当我们调用了self.add的时候,就返回了这个ViewController *(^)(float)类型的block,一旦我们self.add()加了这个(),block就被执行了,执行的返回值就是一个ViewController,也就是block内部的返回值self,所以self.add()的返回值就是self,既然已经是self了,调用自己的函数也就不过分了吧,那么就可以继续self.add().add().add().minus()等操作了
综上所述,我们要计算的东西的实现就是

float result = self.add(2).add(3).minus(1).multiply(3).divide(4).giveMeResult;

你可能感兴趣的:(iOS函数式编程和链式编程的实现)