問題起因
runBlocking的context引數有默認值,但是在Android Studio中查看源代碼,發現源代碼中定義如下:
@Throws(InterruptedException::class)
public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T
這就很奇怪了,因為doc中明明注釋稱context引數具有默認值,而且官方檔案給出的簽名如下:
expect fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T
并且Kotlin在Github倉庫上的源代碼也確實與IDE中一致,
而且實際除錯時可以發現確實傳入了默認引數,那么到底是怎么回事呢?
真相
經過了反編譯、查看檔案與倉庫多次對照后,終于發現問題所在:
問題的關鍵在于expect和actual,初學者(比如我)可能會簡單地不怎么注意函式簽名的這一部分,然而正是這里造成了默認引數在源代碼中令人困惑的現象!
由于expect定義處已經給出了默認引數,因此當呼叫到actual函式時,確實可以起到傳入默認引數的作用,然而,令人十分困惑的是,在IDE中查找函式位置只能溯源到actual的函式而不是expect部分,因此很可能產生誤解,
吃一塹長一智,以后再遇到類似地情況,請注意方法簽名是否有actual!默認引數可能定義在expect部分中!另外,優先查看官方檔案,IDE溯源代碼可能產生誤解,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/458581.html
標籤:Android
上一篇:招募兼職軟體開發、程式定制人員
