YIOS是什么?
YIOS是什么?yield是生成器中的特有用法,而生成器是一種可以封閉整個(gè)運(yùn)行狀態(tài)、可以隨時(shí)暫停繼續(xù)的模型,從傳統(tǒng)的程序觀點(diǎn)是很難描述它的,但是似乎跟函數(shù)式編程有比較密切的關(guān)系(雖然我并沒(méi)有學(xué)過(guò)函數(shù)式
YIOS是什么?
yield是生成器中的特有用法,而生成器是一種可以封閉整個(gè)運(yùn)行狀態(tài)、可以隨時(shí)暫停繼續(xù)的模型,從傳統(tǒng)的程序觀點(diǎn)是很難描述它的,但是似乎跟函數(shù)式編程有比較密切的關(guān)系(雖然我并沒(méi)有學(xué)過(guò)函數(shù)式編程……)設(shè)想我們有一個(gè)函數(shù),它返回一個(gè)序列,這個(gè)序列可以是無(wú)限長(zhǎng)的(也可以是有限長(zhǎng))。當(dāng)然,無(wú)限長(zhǎng)的序列我們是表示不出來(lái)的,內(nèi)存會(huì)爆。但是我們通??梢园阉硎境梢粋€(gè)廣義表,它的第一項(xiàng)是下一個(gè)值,而第二項(xiàng)是剩下所有值用同樣方法形成的廣義表,也就是說(shuō)我們把返回值:改寫成如果原始的序列是有限長(zhǎng)的,則最終某個(gè)子表里只有一個(gè)元素。這樣的形式對(duì)傳統(tǒng)的程序來(lái)說(shuō)似乎沒(méi)什么用,但是一般我們認(rèn)為廣義表是可以延遲求值的,也就是說(shuō)我們可以每次取一個(gè)值,然后需要的時(shí)候再去計(jì)算下一個(gè)子表。這個(gè)模型就對(duì)應(yīng)到了生成器。我們每次調(diào)用生成器讓它返回下一個(gè)值的時(shí)候,就相當(dāng)于取出子表中第一項(xiàng)的同時(shí),將生成器推進(jìn)到了下一個(gè)子表中,這樣我們得生成器就可以返回任意有限甚至無(wú)限多個(gè)元素,而且只在需要的時(shí)候才計(jì)算出它們。接下來(lái)我們知道,返回一個(gè)子表,和返回一個(gè)“返回子表的函數(shù)”,其實(shí)沒(méi)有什么區(qū)別。那么如果返回的這個(gè)函數(shù)還能接受參數(shù)呢?我們可以在獲取上一個(gè)值之后,給這個(gè)生成器傳入一個(gè)新的值,從而影響之后返回的結(jié)果,這個(gè)就是yield表達(dá)式的作用了,它返回一個(gè)值,這個(gè)值實(shí)際上是從外部傳入的,也就是我們看到的輸入的參數(shù)。但是生成器其實(shí)又跟真正的函數(shù)式編程不同,它是在傳統(tǒng)編程方法當(dāng)中實(shí)現(xiàn)一個(gè)這樣功能結(jié)構(gòu)的語(yǔ)法,真正的函數(shù)式編程自然會(huì)毫不猶豫地將它寫成尾遞歸的形式。但我們也知道,尾遞歸可以轉(zhuǎn)化成循環(huán),那么生成器通常就是將尾遞歸轉(zhuǎn)化成循環(huán)之后的形式,它的內(nèi)部封閉了所有本來(lái)應(yīng)該在遞歸中作為參數(shù)傳遞的狀態(tài),這樣我們可以用傳統(tǒng)的編程的方法來(lái)寫這個(gè)生成器,這樣在許多時(shí)候是比較方便的,比如說(shuō)問(wèn)題異常復(fù)雜,比如說(shuō)需要調(diào)用I/O等非冪等的方法的時(shí)候。由于生成器的第二種形式可以看成每次都隱含返回一個(gè)接受參數(shù)的函數(shù),這個(gè)函數(shù)可以代替異步編程中的回調(diào)函數(shù),從而用生成器編寫異步過(guò)程,這種方法許多時(shí)候也被叫做協(xié)程,但從一開始就強(qiáng)調(diào)生成器的這種用法我覺(jué)得是不科學(xué)的,它其實(shí)只是用生成器代替了異步回調(diào)函數(shù)而已,并不是自己就具有獨(dú)立執(zhí)行的能力,把生成器叫做協(xié)程容易讓初學(xué)者忽略了調(diào)度器在異步程序中的重要作用,造成誤導(dǎo)。