iOS 函數(shù)式編程、鏈?zhǔn)骄幊?/h2>

最近看一本書,提到了關(guān)于函數(shù)式編程和響應(yīng)式編程,就特地在網(wǎng)上找資料,整理整理,理解理解其差異,就順帶寫了這個(gè)。

一、函數(shù)式編程

首先,要去了解了解block,可以看看這篇文章Objective-C中的block。

1、解釋

Functional Programming
函數(shù)式編程其實(shí)是一種編程思想、編程方式,這個(gè)編程思想的重點(diǎn)是在函數(shù)上的理解,特別是對(duì)函數(shù)狀態(tài)的理解,更深的是函數(shù)在Stateless的狀態(tài)。

2、特性:

函數(shù)式編程強(qiáng)調(diào)的是純函數(shù)編程,也就是不依賴外部狀態(tài),也不改變外部狀態(tài)。簡(jiǎn)單的理解就是,函數(shù)調(diào)用的結(jié)果不依賴調(diào)用的時(shí)間和空間狀態(tài);同時(shí),這種函數(shù)是線程安全的。

  時(shí)間狀態(tài):變量一旦有了狀態(tài),它就有可能隨著時(shí)間而發(fā)生變化,時(shí)間是最不可預(yù)知的因素;
  空間狀態(tài):如果把一個(gè)線程看成一個(gè)獨(dú)立的空間,在程序的世界當(dāng)中,空間會(huì)產(chǎn)生交叉重疊。一個(gè)變量如果可以被兩個(gè)線程同時(shí)訪問,它的值如果可以在兩個(gè)空間發(fā)生變化,這個(gè)變量同樣變得很危險(xiǎn)。
3 常規(guī)關(guān)鍵字
  高階函數(shù):參數(shù)為函數(shù)或返回值為函數(shù)的函數(shù)  //函數(shù)式編程就是指這種高度抽象的編程范式
  惰性求值:就是我們常??谡Z(yǔ)化的“懶加載”,表達(dá)式賦值給變量時(shí),并不會(huì)馬上參與計(jì)算求值,是當(dāng)變量被調(diào)用時(shí)候才會(huì)計(jì)算。通過按需加載計(jì)算提升性能

其實(shí)函數(shù)式編程并不會(huì)減少我們的代碼量,它只是改變的只是我們書寫代碼的方式而已。這可能需要適應(yīng)一段時(shí)間。

二、鏈?zhǔn)骄幊?/h2>

平時(shí)我們經(jīng)常在項(xiàng)目里使用Masonry,使用的時(shí)候大致會(huì)這樣寫:

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

在里面我們看到這樣的句子:

make.left.equalTo(self.view).with.offset(10);

通過"."語(yǔ)法,將需要執(zhí)行的代碼連續(xù)的書寫,就叫做鏈?zhǔn)骄幊蹋沟么a簡(jiǎn)單易懂。
現(xiàn)在要實(shí)現(xiàn)這種效果,我們舉一個(gè)例子,由最常見的實(shí)現(xiàn)方式,然后逐步修改,最后實(shí)現(xiàn)想要的最終效果,比如2-3+4。
想要實(shí)現(xiàn)的最后的效果為:

self.add(2).subtract(3).add(4).getResult;

1、最常見的實(shí)現(xiàn)
//  TestLinked.h
@interface TestLinked : NSObject
- (void)add:(NSInteger)value;
- (void)subtract:(NSInteger)value;
- (NSInteger)getResult;
@end
//  TestLinked.m
@interface TestLinked ()
@property (nonatomic, assign) NSInteger result;
@end

@implementation TestLinked
/**
    第一種實(shí)現(xiàn)方式
*/
- (void)add:(NSInteger)value{
    self.result += value;
}
- (void)subtract:(NSInteger)value{
    self.result -= value;
}
- (NSInteger)getResult{
    return self.result;
}
- (void)testRun_1{
    [self add:2];
    [self subtract:3];
    [self add:4];
    NSInteger result = [self getResult];
    NSLog(@"result = %ld",(long)result);
}
@end

第一種實(shí)現(xiàn)就是簡(jiǎn)單的實(shí)現(xiàn)計(jì)算,逐步完成。
但是我們想實(shí)現(xiàn)函數(shù)的這樣實(shí)現(xiàn)時(shí):add(2),我們第一反應(yīng)的是block,因?yàn)閎lock的使用時(shí),就是直接用”()“來(lái)表示,那么我們可以考慮將函數(shù)的返回值改為block,這樣就可以實(shí)現(xiàn)"()"的使用了,也就貼合我們目的的使用方式了。

2、將函數(shù)的返回值全部更換為block
- (void (^)(NSInteger))add;
- (void (^)(NSInteger))subtract;
- (NSInteger)getResult;

具體的實(shí)現(xiàn)如下:

/**
 將函數(shù)的返回值變成block
 */
- (void (^)(NSInteger))add{
    __weak typeof(self) wself = self;
    void (^addResult)(NSInteger) = ^(NSInteger value){
        wself.result += value;
    };
    return addResult;
}
- (void (^)(NSInteger))subtract{
    __weak typeof(self) wself = self;
    void (^subtractResult)(NSInteger) = ^(NSInteger value){
        wself.result -= value;
    };
    return subtractResult;
}
- (NSInteger)getResult{
    return self.result;
}

- (void)testRun_2{
    //逐步寫法
    void (^addBlock)(NSInteger) = self.add;
    void (^subtractBlock)(NSInteger) = self.subtract;
    addBlock(2);
    subtractBlock(3);
    addBlock(4);

    //簡(jiǎn)寫
    self.add(2);
    self.subtract(3);
    self.add(4);

    NSInteger result = [self getResult];
    NSLog(@"result = %ld",(long)result);
}

在調(diào)用的地方,寫了兩種方式的實(shí)現(xiàn),一種是逐步的,一種是直接簡(jiǎn)寫。我們看到了基本的實(shí)現(xiàn)。在代碼中。我們看到這樣一個(gè)地方

    self.add(2);
    self.subtract(3);
    self.add(4);

在里面,我們看到每次調(diào)用都是用self來(lái)發(fā)起的,如果想實(shí)現(xiàn)這種效果

 self.add(2).subtract(3).add(4);

那么我們需要對(duì)self.add(2)這個(gè)block提供返回值,而返回值的類型也就是self,即寫到的TestLinked類型,這樣就可以實(shí)現(xiàn)連續(xù)的調(diào)用。

3、為block添加返回值
- (TestLinked *(^)(NSInteger))add;
- (TestLinked *(^)(NSInteger))subtract;
- (NSInteger)getResult;
/**
 為block添加返回值,返回值類型為TestLinked
 */
- (TestLinked *(^)(NSInteger))add{
    __weak typeof(self) wself = self;
    TestLinked *(^addResult)(NSInteger) = ^(NSInteger value){
        wself.result += value;
        return wself;
    };
    return addResult;
}
- (TestLinked *(^)(NSInteger))subtract{
    __weak typeof(self) wself = self;
    TestLinked *(^subtractResult)(NSInteger) = ^(NSInteger value){
        wself.result -= value;
        return wself;
    };
    return subtractResult;
}
- (NSInteger)getResult{
    return self.result;
}
- (void)testRun_4{
    NSInteger result = self.add(2).subtract(3).add(4).getResult;
    NSLog(@"result = %ld",(long)result);
}

這樣就實(shí)現(xiàn)了鏈?zhǔn)降男Ч?/p>

逐步實(shí)現(xiàn)這個(gè)過程,其實(shí)是一步一步的改變方法的實(shí)現(xiàn),最后滿足要求而已。關(guān)鍵里面的使用是block。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容