Вы можете хранить их в 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)