最近看一本書,提到了關(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。