Reputation: 128
fun getApple(): Apple = {...}
fun setOrange(orange: Orange) {...}
val funMap = hashMapOf("getApple" to this::getApple, "setOrange" to this::setOrange)
funMap["getApple"]()
I want to put the method on the map. Then get the method by string, but can't be invoked if function type different. Any other way to convert the string to function?
---- update ----
I used to use the java reflection before, I am looking for a more efficient way
Upvotes: 1
Views: 1907
Reputation: 4753
It's possible, but your map has type Map<String, KFunction<Any>>
. For KFunction
you have method .call
and .callBy(Map<KParameter, Any>)
. So, see this example (I've also added logging when function invoked):
class StackStringFunction {
data class Apple(val size: Int = 1)
data class Orange(val color: String = "orange")
fun getApple(): Apple {
println("Calling getApple()")
return Apple()
}
fun setOrange(orange: Orange) {
println("Calling setOrange(Orange) with param $orange")
}
val funMap = hashMapOf("getApple" to this::getApple, "setOrange" to this::setOrange)
}
// Invocation example:
with(StackStringFunction()) {
this.funMap["getApple"]?.call()
this.funMap["getApple"]?.callBy(mapOf())
this.funMap["setOrange"]?.call(StackStringFunction.Orange())
this.funMap["setOrange"]?.callBy(mapOf(this.funMap["setOrange"]!!.parameters[0]to StackStringFunction.Orange()))
}
And the output:
Calling getApple()
Calling getApple()
Calling setOrange(Orange) with param Orange(color=orange)
Calling setOrange(Orange) with param Orange(color=orange)
As you see, via ::sth
you obtain not a lambda, but KFunction
, and using KFunction interface you are able to call those methods.
Upvotes: 2