如果我定义
class MyF : KFunction0<Int> {
override val name: String = "f"
override fun invoke() = 42
override val annotations: List<Annotation>
get() = TODO()
....
}
我会写
val f0: KFunction0<Int> = MyF()
assertEquals("f", f0.name)
但如果我尝试
assertEquals(42, f0())
我得到java.lang.ClassCastException: MyF cannot be cast to kotlin.jvm.functions.Function0
如何定义自己的KFunction0
实现?
我无法使用() -> Int
,因为我需要name
属性。
我正在使用Kotlin 1.3.21。
另外-看来我可以跑步
val f02 = MyF()
assertEquals(42, f02())
我的实际用例是Can I convert a Kotlin KFunction1 to a KFunction0 by applying the argument?
答案 0 :(得分:4)
从Kotlin JVM显式实现内部类绝对不是一个好主意。由于某种原因,您在IntelliJ或Android Studio中没有该类的代码完成
您可以改为使用可调用引用,以使Kotlin编译器为您生成所有必需的类。 https://kotlinlang.org/docs/reference/reflection.html#callable-references
NotApplicable
好处-将来的Kotlin版本不太可能破坏该代码(并可能破坏您的继承者类)
如果您需要一个更长的名称,可以这样声明
fun myfun() = 42
val kFunction = ::myfun
println(kFunction.name)
println(kFunction())
答案 1 :(得分:1)
在Kotlin 1.2中,我没有找到KFunction0<T>
,但只有KFunction<T>
,我能够做你想做的事情:
import kotlin.reflect.*
import kotlin.test.assertEquals
class MyKF : KFunction<Int>{ // In Kotlin 1.3 you can extend KFunction0<Int>
override val annotations: List<Annotation>
get() = listOf()
override val isAbstract: Boolean
get() = false
override val isExternal: Boolean
get() = false
override val isFinal: Boolean
get() = true
override val isInfix: Boolean
get() = false
override val isInline: Boolean
get() = false
override val isOpen: Boolean
get() = false
override val isOperator: Boolean
get() = false
override val isSuspend: Boolean
get() = false
override val parameters: List<KParameter>
get() = listOf()
override val typeParameters: List<KTypeParameter>
get() = listOf()
/**
* I am not sure how get proper return type. So... This KFunction will return kotlin.Number.
*/
override val returnType: KType
get() = Int::class.supertypes[0]
override val visibility: KVisibility?
get() = KVisibility.PUBLIC
override fun call(vararg args: Any?): Int {
return 0
}
override fun callBy(args: Map<KParameter, Any?>): Int {
return 0
}
override val name: String
get() = "f"
// Sience Kotlin 1.3
override fun invoke(): Int {
return 0
}
}
fun main(args: Array<String>) {
val kf = MyKF()
assertEquals("f", kf.name)
assertEquals(0, kf.call())
println(kf.returnType)
println(kf.name)
println(kf.call())
pritnln(kf.invoke())
}
稍后我将把Kotlin更新到1.3,然后我将回答完整(如果它在Kotlin 1.3中可用)。
那么您的问题在哪里?也许(只是幸运的猜测)基于returnType
之类的覆盖方法的检查类型?
编辑:
迁移到Kotlin 1.3之后,我可以扩展KFunction0<Int>
而不是KFunction<Int>
。唯一的更改-我的班级也必须覆盖invoke(): Int
。仍然有效!
Edit2:
我不确定我是在IDE中没有看到KFunction0还是在1.3以下的Kotlin中不存在。