[英]Can I get a KFunction from a variable of function type in 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.