簡體   English   中英

為什么 KFunction2 在 Kotlin 中不是可表示類型?

[英]Why is KFunction2 not a denotable type in Kotlin?

假設我們在 Kotlin(版本 1.6.21,針對 JVM 17)中有以下類:

interface Cursor(
    fun seekOrNext(target: String): Boolean
    fun seekOrPrevious(target: String): Boolean
)

我想做的是在高階函數中接受指向這些方法之一的函數指針:

fun moveCursorAndLog(cursor: Cursor, move: ???, target: String): Boolean {
    println("Moving cursor with ${move.name} to '${target}'.")
    return move(cursor, target)
}

問題是:我們必須插入的類型是什么???

  • 它不能是(Cursor, String) -> Boolean ,因為它可以是任何 lambda,我們只能在KFunction上調用.name
  • 它也不能是KFunction ,因為那不允許調用move(cursor, target)

如果我們在 IDE 中這樣寫:

val m = Cursor::seekOrNext

...然后類型提示將告訴我們它是KFunction2<Cursor, String, Boolean> ,這正是我們所需要的。 但是,以下內容:

fun moveCursorAndLog(cursor: Cursor, move: KFunction2<Cursor, String, Boolean>, target: String): Boolean {
    println("Moving cursor with ${move.name} to '${target}'.")
    return move(cursor, target)
}

... 無法編譯,因為我的 IntelliJ 在任何地方都找不到類型KFunction2 (是的,我確保我的類路徑上有kotlin-reflect )。

這讓我相信,雖然KFunction2是 Kotlin 類型系統中的有效類型,但它不是“可表示的”,即我們不能聲明這種類型的方法參數。

真的是這樣嗎,還是我錯過了什么?

除了你可以表示KFunction2嗎? IntelliJ 不會為您提供自動完成功能,但這只是 IntelliJ。 這是錯誤報告。 KFunction2應該在kotlin.reflect包中。

做就是了

import kotlin.reflect.KFunction2

然后你可以這樣做:

fun moveCursorAndLog(cursor: Cursor, move: KFunction2<Cursor, String, Boolean>, target: String): Boolean {
    println("Moving cursor with ${move.name} to '${target}'.")
    return move(cursor, target)
}

這對我來說編譯得很好。

當然,僅拼寫整個完全限定名稱而不進行導入也是可以的。

也就是說, KFunctionX確實有點特別。 它們由編譯器動態生成,由BuiltInFictitiousFunctionClassFactory.kt ,這可能解釋了 IntelliJ 存在上述錯誤的原因。

import kotlin.reflect.KFunction1

interface Cursor {
  fun seekOrNext(target: String): Boolean
  fun seekOrPrevious(target: String): Boolean
}

fun moveCursorAndLog(move: KFunction1<String, Boolean>, target: String): Boolean {
  println("Moving cursor with ${move.name} to '${target}'.")
  return move(target)
}

class CursorImpl : Cursor {

  override fun seekOrNext(target: String): Boolean {
    return true
  }

  override fun seekOrPrevious(target: String): Boolean {
    return true
  }

}

val cursorInstance = CursorImpl()
val move = cursorInstance::seekOrNext
moveCursorAndLog(move, "somewhere else")
// Output: "Moving cursor with seekOrNext to 'somewhere else'."

暫無
暫無

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

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