Wenxiu Jin
Wenxiu Jin

Reputation: 128

How to convert String to Function in Kotlin?

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

Answers (1)

Cililing
Cililing

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

Related Questions