Kotlin協程核心庫分析 7 Sequence

2021-10-05 15:02:24 字數 4041 閱讀 1866

sequence是乙個kotlin序列生成器物件,其他語言也都有其相對應的api(如dart)。

簡單看下如下例子

fun

foo(

): sequence

= sequence

}fun

main()

}

輸出:

1

23

fun

foo(

): sequence

= sequence

}fun

main()

}

輸出:

1

開始列印第二個

2開始列印第三個

3

如果不清楚語言的序列生成器的話,可以建議可以多「食用」幾次。

再講這塊內容之前補充乙個協程api

此函式用於限制協程函式呼叫任意接受者者以外的擴充套件函式。

舉個例子:

@restrictssuspension

class main

}fun

testrestrictsuspend

(block:

suspend main.()

-> unit)

suspend

funtestsuspend()

funmain()

}

testrestrictsuspend傳入的協程函式僅能呼叫main內部的協程函式。大家可以自己試試。

由於sequence內部採用協程作為實現,所以才歸入協程系列分析,同時也為冷熱流做鋪墊。

首先我們先看sequence函式宣告。

public

funsequence

(@builderinference block:

suspend sequencescope.(

)-> unit)

: sequence

= sequence

當你第一次看到這個函式宣告的時候也許會很納悶sequence= sequence, 因為sequences是乙個類,那後面sequence是什麼語法?類可以這樣宣告?

其實這裡注意:

首先我們檢視sequence類物件:

public

inte***ce sequence<

out t>

從上可以看出核心是在於返回的迭代器,所以介面沒有太多東西可以描述.

public

inline

funsequence

(crossinline iterator:()

-> iterator

): sequence

=object

: sequence

返回乙個sequence的匿名內部類,其返回的迭代器由傳入的函式返回。

所以我們最終只需要關於iterator這個函式:

sequence
public

funiterator

(@builderinference block:

suspend sequencescope.(

)-> unit)

: iterator

我們看到函式內部建立了乙個協程,然後接受者和完成監聽都是sequencebuilderiterator物件,這裡不難看出sequencebuilderiterator實現了迭代演算法,和乙個continuation的介面(協程完成監聽必須是這個子類)。

我們來逐一看下這個類由於比較簡單我直接在原始碼注釋即可

private

typealias state = int

private

const

val state_notready: state =

0private

const

val state_manynotready: state =

1private

const

val state_manyready: state =

2private

const

val state_ready: state =

3private

const

val state_done: state =

4private

const

val state_failed: state =

5private

class sequencebuilderiterator

: sequencescope()

, iterator

, continuation

state_manynotready ->

if(nextiterator!!

.hasnext()

)else

state_done ->

return

false

state_ready, state_manyready ->

return

true

else

->

throw

exceptionalstate()

}

state = state_failed

val step = nextstep!!

nextstep =

null

//恢復協程狀態機,那麼會進入我們sequence傳入的lambda中,

//直到呼叫yild,我們先看yild實現

step.

resume

(unit)}}

override

funnext()

: t

state_ready ->

else

->

throw

exceptionalstate()

}}private

funnextnotready()

: t

private

funexceptionalstate()

: throwable =

when

(state)

override

suspend

funyield

(value: t)

}//這裡和yield差不多就不講解了

override

suspend

funyieldall

(iterator: iterator)}

// completion continuation implementation

override

funresumewith

(result: result

)override

val context: coroutinecontext

get()

= emptycoroutinecontext

}

由於整體比較簡單所以不做過大解釋,大致可以理解為:

hasnext恢復協程狀態機,進入我們的lambda表示式

lambda表示式yield產生乙個數值,然後掛起函式

next函式返回yield數值

Kotlin協程筆記

會阻塞主線程,等待協程執行完,才會繼續執行主線程 不會阻塞主線程,返回job型別的物件 var job globalscope.launch 3 async 用於啟動乙個非同步協程任務,與launch用法基本一樣,不阻塞執行緒,區別在於 async的返回值是deferred,將最後乙個封裝成了該物件...

Kotlin協程快速入門

協程,全稱可以譯作協同程式,很多語言都有這個概念和具體實現,之前入門python的時候接觸過,而kotlin其實也早就有這個擴充套件功能庫了,只不過之前一直處於實驗階段,不過前段時間1.0的正式版終於出了,網上的相關部落格也多了起來,經過這幾天的學習我也來做下小結吧。首先貼下kotlin協程的官方g...

Kotlin 協程學習記錄

kotlin 協程 implementation org.jetbrains.kotlinx kotlinx coroutines core 1.2.1 1 runblocking 會一直阻塞到塊中的 執行完 runblocking job.join 等待直到子協程執行結束 主協程與後台作業的持續時...