函數(shù)響應(yīng)式編程概述

什么是編程?

范式概念
需求-模式-代碼

面向過程 vs 面向?qū)ο?/h4>
面向過程和面向?qū)ο?/div>

命令式編程 vs 函數(shù)式編程

命令式語言下的響應(yīng)式編程

聲明式編程

函數(shù)響應(yīng)式編程

  • 滿足函數(shù)式的一些特性
  • 面向離散事件流
  • 離散時(shí)間流操作

什么是ReactiveCocoa?

  • Github Mac客戶端副產(chǎn)物
  • FRP在Cocoa框架下的實(shí)現(xiàn)
  • 富含了Cocoa框架多種組件
  • 提供基于時(shí)間變化的數(shù)據(jù)流的組合和實(shí)現(xiàn)
  • 簡稱RAC

理論基礎(chǔ)

理解基于時(shí)間變化的數(shù)據(jù)流

  • 如何創(chuàng)建
  • 如何遍歷
  • 如何停止遍歷

基于時(shí)間變化的數(shù)據(jù)流可操作范圍

更多操作

  • 加殼


函數(shù)式編程四個(gè)特性

  • 閉包&高階函數(shù)
  • 惰性計(jì)算
  • 不改變狀態(tài)
  • 遞歸

核心組件

RACStream的兩個(gè)子類

Sequence vs Signal

  • Pull-driver vs Push-driver
  • Data vs Event
  • 其他差異

RACSequence使用方法

RACSignal使用示例

Signal Subscriber Disposable

Scheduler

  • 用來做調(diào)度
  • 代替GCD
  • 異步和并發(fā)

Cocoa框架適配工具

作業(yè)

一、判斷題:

  • (1)函數(shù)式編程是面向?qū)ο缶幊痰纳?jí)版

錯(cuò)。函數(shù)式編程和鏈?zhǔn)骄幊滔鄬?yīng),所以說并不是升級(jí)版,而是不同的編程范式;編程的思想或者模式是根據(jù)需求來的,既然是根據(jù)需求來的就不存在升級(jí)或者降級(jí)。

  • (2)組成鏈?zhǔn)秸{(diào)用的必要條件就是在方法里面返回對象自己
    錯(cuò)。只要返回的是相同的類型的對象就可以,未必要是自己,也返回子類或者其他類,只要這個(gè)鏈?zhǔn)秸{(diào)用可以承載下去。
  • (3)響應(yīng)式編程可以用C語言這樣的語言實(shí)現(xiàn)
  • (4)ReactiveCocoa是基于KVO的一個(gè)開源庫
    錯(cuò)。雖然有些信號(hào)的產(chǎn)生來自KVO,但是有些不是
  • (5)ReactiveCocoa是一個(gè)純函數(shù)式編程的庫
    錯(cuò)。ReactiveCocoa不是一個(gè)純函數(shù)式編程的庫,因?yàn)樗旧頉]有建立在純函數(shù)式的環(huán)境
  • (6)下面的函數(shù)由于有賦值所以不是一個(gè)純函數(shù)
typedef int(^FunctionType1)(int x);

typedef int(^FunctionType2)(int x, int y);



FunctionType1 someFunction(FunctionType2 func, int x, FunctionType1 valueMap) {

    int nextValue = valueMap(x);

    return ^int(int y) {

        return func(nextValue, y);

    };

}

雖然有賦值,但是每次固定輸入都能得到固定的輸出,并且沒有改變外部的狀態(tài),是純函數(shù)。

二、問答題:

想到了master,slave這個(gè)經(jīng)典的場景。一個(gè)黑心的老板有5個(gè)程序員,這里有100個(gè)需求。每個(gè)程序員完成后,告訴老板說我做完了,再來一個(gè)需求。這就是pull driver,接收方主動(dòng)來拿。如果老板不管這個(gè)人忙不忙,需求來了就直接分配給某個(gè)程序員,這就是push driver,源直接推送給某個(gè)接收方

  • (2)怎么理解函數(shù)式語言中的引用透明?

引用透明(Referential transparency),指的是函數(shù)的運(yùn)行不依賴于外部變量或"狀態(tài)",只依賴于輸入的參數(shù),任何時(shí)候只要參數(shù)相同,引用函數(shù)所得到的返回值總是相同的。

引用透明(Referential Transparent)的概念與函數(shù)的副作用相關(guān),且受其影響。如果程序中任意兩處具有相同輸入值的函數(shù)調(diào)用能夠互相置換,而不影響程序的動(dòng)作,那么該程序就具有引用透明性。它的優(yōu)點(diǎn)是比非引用透明的語言的語義更容易理解,不那么晦澀。純函數(shù)式語言沒有變量,所以它們都具有引用透明性。

  • (3)函數(shù)式語言主張不變量的原因是什么?
    • 保證和數(shù)學(xué)模型的親密性
  • 解決了線程的安全
  • 讓編譯器更好的優(yōu)化

其次通過聲明區(qū)分可變和不可變性降低了復(fù)雜度。我們可以更加關(guān)注變化的value,增加了一種語義。當(dāng)我們看到一個(gè)值聲明是可變的,我們會(huì)知道這個(gè)值在后面的代碼中會(huì)被賦值。

三、編程題:

  • (1)基于變量不可變(任何變量不允許二次賦值)來實(shí)現(xiàn)一個(gè)計(jì)算最大值的函數(shù),定義如下

int max(int *array, int count)


    int max(int *array, int count){
    
    if (count < 1) return INT_MIN;
 
    if (count == 1) return array[0];
    int headMax = max(array, count - 1);
    
    return headMax > array[count - 1] ? headMax : array[count - 1];
   
}
  • (2)自由發(fā)揮寫一個(gè)高階函數(shù)應(yīng)用的例子,要求必須有返回函數(shù)的部分
    int array[] = {1, 2, 3, 4, 8, -1};
    int max = fold(array, sizeof(array) / sizeof(typeof(array)), ^int(int acc, int next) {
        return acc > next ? acc : next;
    }, INT_MIN);

    int fold(int *array, int count, ReduceType block,int first){
    if (count == 0) return first;
    
    return fold(array + 1, count - 1, block, block(first, array[0]));
}
typedef BOOL (^ConditionType)(int a);
int find(int *array, int count, ConditionType finder)
{
    if (count == 0) return INT_MIN;
    if (finder(array[0])) {
        return array[0];
    }
    return find(array + 1, count - 1, finder);
}

ConditionType not(ConditionType block)
{
    return ^BOOL(int a){
        return !block(a);
    };
}
main(){
ConditionType even = ^BOOL(int v){
        return v % 2 ==0;
    };
    int value = find(array, sizeof(array) / sizeof(int), even);
}

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

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