Kotlin:在变量中存储任何类型的函数引用

Kotlin:在变量中存储任何类型的函数引用,kotlin,Kotlin,是否可能有一个变量可以保存任何类型的函数 比如: fun method1(par: Boolean){} fun method2(par: Boolean) : Int{return 1} fun method3(par: Boolean, par2: Boolean) : Int{return 1} var funtionHolder : ((Any)->Any) ?= null //What should I write here?? so to h

是否可能有一个变量可以保存任何类型的函数

比如:

    fun method1(par: Boolean){}
    fun method2(par: Boolean) : Int{return 1}
    fun method3(par: Boolean, par2: Boolean) : Int{return 1}

    var funtionHolder : ((Any)->Any) ?= null  //What should I write here?? so to hold any type of function

   fun method4(){
        .........
        funtionHolder = ::method1  //getting compile time error
        .........
        funtionHolder = ::method2  //getting compile time error
        .........
        funtionHolder = ::method3  //getting compile time error
    }
在保存函数_引用之后,我需要稍后调用它。所以我还需要保存它的参数类型和状态。

您可以将它们保存在一个或其超类中,因为您对参数列表和返回类型一无所知,所以您必须转到可以在该抽象级别引用的内容。然后可以使用
call()
callBy()
方法更一般地调用这些实例。(这需要
kotlin反映
依赖关系)。为了做一些更安全的事情,并像普通函数一样调用,您必须在以后回溯到特定的函数类型

如果要避免这种情况,您需要将签名统一到可以使用其他函数类型指向的内容(即
KFunction1
KFunction2
)。否则,您将如何调用该函数,此时您将决定如何使用它,因为您删除了所有允许轻松调用该函数的信息

val functionHolder1: KFunction<Any> = ::method1 // success!
val functionHolder2: KFunction<Any> = ::method2 // success!
val functionHolder3: KFunction<Any> = ::method3 // success!
invoke
函数上不需要泛型返回类型,只需使其返回
Any
或将其称为
functionHolder()
,但如果您知道返回的预期效果,则很好。您可以根据实际用例决定在那里做什么。也不需要为无参数设置特殊情况,只需不传递任何参数,例如,
DeferredFunction(::otherFunc)

您可以将它们保存在一个或其超类中,因为您对参数列表和返回类型一无所知,所以您必须转到可以在该抽象级别引用的对象。然后可以使用
call()
callBy()
方法更一般地调用这些实例。(这需要
kotlin反映
依赖关系)。为了做一些更安全的事情,并像普通函数一样调用,您必须在以后回溯到特定的函数类型

如果要避免这种情况,您需要将签名统一到可以使用其他函数类型指向的内容(即
KFunction1
KFunction2
)。否则,您将如何调用该函数,此时您将决定如何使用它,因为您删除了所有允许轻松调用该函数的信息

val functionHolder1: KFunction<Any> = ::method1 // success!
val functionHolder2: KFunction<Any> = ::method2 // success!
val functionHolder3: KFunction<Any> = ::method3 // success!

invoke
函数上不需要泛型返回类型,只需使其返回
Any
或将其称为
functionHolder()
,但如果您知道返回的预期效果,则很好。您可以根据实际用例决定在那里做什么。也不需要为无参数设置特殊情况,只需不传递任何参数,即延迟函数(::otherFunc)

否。Kotlin是静态类型语言,不允许这样做。否则,当调用时会发生什么

functionHolder->invoke(3)

当functionHolder被分配了一个不带参数的lamda时?

否。Kotlin是静态类型语言,不允许这样做。否则,当调用时会发生什么

functionHolder->invoke(3)

当functionHolder被分配一个不带参数的lamda时?

参考Jayson的答案,通过使用vararg扩展运算符(*)添加额外的代码来保持函数的状态

    var functionHolder: KFunction<Any> ?= null
    var paramsHolder : Array<out Any?> ?= null

    fun hold(functionReference : KFunction<Any>, vararg args : Any?) {
        this.functionHolder = functionReference
        this.paramsHolder = args
    }

    fun release() {
        if (functionHolder != null) {
            if (paramsHolder != null) {
                functionHolder?.call(*paramsHolder!!)
            } else {
                functionHolder?.call()
            }
        }
    }

    fun method3(par: Boolean, par2: Boolean) : Int{return 1}
    hold(::method3, true, false)
    release()//it works

参考Jayson的回答,通过使用vararg扩展运算符(*)添加了额外的代码来保持函数的状态

    var functionHolder: KFunction<Any> ?= null
    var paramsHolder : Array<out Any?> ?= null

    fun hold(functionReference : KFunction<Any>, vararg args : Any?) {
        this.functionHolder = functionReference
        this.paramsHolder = args
    }

    fun release() {
        if (functionHolder != null) {
            if (paramsHolder != null) {
                functionHolder?.call(*paramsHolder!!)
            } else {
                functionHolder?.call()
            }
        }
    }

    fun method3(par: Boolean, par2: Boolean) : Int{return 1}
    hold(::method3, true, false)
    release()//it works

哇!它起作用了。是的,它需要依赖关系kotlin reflect。我使用spread运算符和vararg来保持函数状态。哇!!它起作用了。是的,它需要依赖关系kotlin reflect。我使用了spread运算符和vararg来保持函数状态。Shanki,我更新了我的答案,做了一些类似的事情,但更加封装,请看一下。答案越少,一个更完整的单一答案越好:-)Shanki,我更新了我的答案,做了一些类似的事情,但更加封装,请看一下。答案越少,单一答案越完整越好:-)