簡體   English   中英

混淆 function 類型在 Kotlin 中的用法

[英]Confusing function type usage in Kotlin

我正在閱讀 kotlin 協程源代碼。

請參閱下面的代碼快照:

  public operator fun <R, T> invoke(block: suspend R.() -> T, receiver: R, completion: Continuation<T>): Unit =
        when (this) {
            DEFAULT -> block.startCoroutineCancellable(receiver, completion)
            ATOMIC -> block.startCoroutine(receiver, completion)
            UNDISPATCHED -> block.startCoroutineUndispatched(receiver, completion)
            LAZY -> Unit // will start lazily
        }

在 CoroutineStart.kt 中

  internal fun <R, T> (suspend (R) -> T).startCoroutineCancellable(
    receiver: R, completion: Continuation<T>,
    onCancellation: ((cause: Throwable) -> Unit)? = null
) =
    runSafely(completion) {
        createCoroutineUnintercepted(receiver, completion).intercepted().resumeCancellableWith(Result.success(Unit), onCancellation)
    }

在 Cancellable.kt 中

我的困惑是:

作為 function 類型為R.() -> Tblock ,它如何調用startCoroutineCancellable類型為(R) -> T的 function

這在語言規范的“ Function Types ”部分(強調我的)中進行了解釋。

具有接收FTR的 function 類型

FTR(RT, A1, A2, ... An) -> R

[...]

從類型系統的角度來看,它相當於下面的 function 類型

FTR(RT, A1, A2, ... An) -> R ≡ FT(RT, A1, A2, ... An) -> R

即接收者被認為是其 function 類型的另一個參數。

[...] 例如,這兩種類型等同於 w.r.t。 類型系統

Int.(Int) -> String (Int, Int) -> String

因此R.() -> T的實例完全可以用作(R) -> T上擴展的接收者,反之亦然,因為類型系統將它們視為同一事物。

請注意,這兩種類型在重載決議的上下文中是不同的。 例如,如果你說someInt.bar() ,並且 scope 中有兩個bar ,一個類型為Int.() -> Unit ,另一個類型為(Int) -> Unit ,那么重載解析將知道這些是具有不同類型的函數並選擇前一個。

旁注: startCoroutineCancellableinvoke中使用的 function 類型在技術上暫停了 function 類型,但上面說的仍然適用。

R.() -> T(R) -> T從調用者的角度來看是非常相似的 function 類型。 他們只收到R並返回T 它們的主要區別在於身體的角度。 看這個例子:

val f1: Int.() -> String = { toString() }
val f2: (Int) -> String = f1
val f3: Int.() -> String = f2

如我們所見,我們可以在兩種類型之間自由轉換,甚至無需顯式強制轉換。

一種簡明扼要的表達方式是,使用接收者定義的 function 類型與將接收者作為第一個參數移入參數的簽名具有相同的簽名。 它們幾乎在任何地方都可以互換,除非使用 lambda 表達式來表示它們,以及調用它們時。 您可以調用帶有接收器的 function ,並將接收器轉換為第一個參數(反之亦然,在其第一個參數的實例上調用無接收器 function )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM