Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin send function arguments using a data class

Let's say I have class:

class Foo {
   fun doSomething(param1: Int, param2: String, param3: String) 
}

and a data class

data class Params(
   val param1: Int,
   val param2: String,
   val param3: String)

Now I want to use the data class arguments to send them to the function, is there a way to do that? Lets say something similar to:

val myParams = Params(1, "2", "3")
val foo = Foo()
foo.doSomething(myparams)

Or by some sort of transformation or method naming. as:

 execute(foo, foo::doSomething, myParams)
like image 565
htafoya Avatar asked Mar 24 '26 07:03

htafoya


1 Answers

I doubt this is possible in Kotlin without some tricks. Possible solutions are reflection API and code generation.

Example using reflection:

fun main() {
    val myParams = Params(1, "2", "3")
    val foo = Foo()

    invokeWithParams(foo::doSomething, myParams)
}

fun <T : Any, R> invokeWithParams(func: KFunction<R>, params: T): R {
    val paramValues = func.parameters.map { kparam ->
        (params::class as KClass<T>)
            .memberProperties
            .single { it.name == kparam.name }
            .get(params)
    }.toTypedArray()
    return func.call(*paramValues)
}

It should work for static functions, member functions, and extension functions. It may fail with some rarer cases. You should probably add some error handling, e.g. checks if params match.

It won't work on anything else than JVM as reflection is still very limited on other targets.

Also, I'm not entirely sure about this unsafe cast. I think it can't fail, but I'm not 100% sure about it.

Update:

We can make it a little more funny by converting the function to extension operator invoke:

operator fun <T : Any, R> KFunction<R>.invoke(params: T): R

Then we can use it with any function like this:

(foo::doSomething)(myParams)

I'm not sure if this is a good idea though as it is more confusing than an explicit call to the utility function.

like image 171
broot Avatar answered Mar 26 '26 08:03

broot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!