代码之家  ›  专栏  ›  技术社区  ›  Duncan McGregor Evgeniy Dorofeev

如何在Kotlin中实现kFunction?

  •  2
  • Duncan McGregor Evgeniy Dorofeev  · 技术社区  · 7 年前

    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 财产。

    另外-看来我可以跑

    val f02 = MyF()
    assertEquals(42, f02())
    

    我的实际用例是 Can I convert a Kotlin KFunction1 to a KFunction0 by applying the argument?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Eugene Petrenko    7 年前

    从Kotlin JVM显式实现一个内部类肯定不是一个好主意。由于某种原因,IntelliJ或Android Studio中没有该类的代码完成

    您可以改用可调用引用,使Kotlin编译器为您生成所有必需的类。 https://kotlinlang.org/docs/reference/reflection.html#callable-references

        fun myfun() = 42
        val kFunction = ::myfun
    
    
        println(kFunction.name)
        println(kFunction())
    

    未来版本的Kotlin不太可能破坏该代码(并且可能破坏继承类)

    fun `my function with long name`() = 43
    
        2
  •  1
  •   Cililing    7 年前

    在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 ?

    编辑:

    KFunction0<Int> 而不是 KFunction<Int> . 唯一的改变-我的类也必须重写 invoke(): Int . 仍然有效!

    编辑2:

    我不确定我是没有在IDE中看到KFunction0,还是在低于1.3的Kotlin中没有出现。