是否有可能包含任何类型函数的变量。
赞:
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
}
在保存function_reference之后,我需要稍后调用它。因此,我还需要保留它的参数类型和状态。
答案 0 :(得分:3)
您可以将它们保存在KFunction<Any>
或其超类KCallable<Any>
中,因为您对参数列表一无所知,而对返回类型一无所知,因此您必须去一些可以在该级别引用的内容的抽象。然后可以使用call()
或callBy()
方法更一般地调用这些实例。 (这需要kotlin-reflect
依赖项)。为了更安全地进行操作并像普通函数一样调用,您以后必须将其转换回特定的函数类型。
如果要避免这种情况,则需要将签名统一为可以使用其他函数类型(即KFunction1
或KFunction2
)指向的对象。否则,您将如何称呼它,这时您将要做什么,因为您已删除了所有可以轻松调用该函数的信息。
val functionHolder1: KFunction<Any> = ::method1 // success!
val functionHolder2: KFunction<Any> = ::method2 // success!
val functionHolder3: KFunction<Any> = ::method3 // success!
然后,您可以创建一个DeferredFunction
类,以将它们与要稍后传递的参数一起保存,然后在以后的任何时候调用它。
class DeferredFunction(val function: KFunction<Any>, vararg val params: Any?) {
@Suppress("UNCHECKED_CAST")
operator fun <T> invoke(): T {
return function.call(params) as T
}
}
fun whatever(name: String, age: Int): String {
return "$name of age $age"
}
val functionHolder = DeferredFunction(::whatever, "Fred", 65)
println(functionHolder<String>()) // "Fred of age 65"
您不需要在invoke
函数上使用泛型返回类型,而可以使它返回Any
或将其称为functionHolder<Any>()
,但是如果您知道会发生什么,那就很好了回报。您可以根据您的实际用例决定在那做什么。另外,无需为没有参数的情况提供特殊情况,只需不传递任何参数,即DeferredFunction(::otherFunc)
答案 1 :(得分:0)
参考Jayson的答案,添加了额外的代码,以使用 vararg 和 spread运算符(*)来保持函数的状态。
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
答案 2 :(得分:-1)
不。 Kotlin是静态类型的语言,不允许这样做。否则当调用它时会发生什么?
functionHolder->invoke(3)
并且为functionHolder分配了不带参数的lamda吗?