Kotlin 使用数据 class 发送函数参数

Kotlin send function arguments using a data class

假设我有 class:

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

和一个数据class

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

现在我想使用数据 class 参数将它们发送到函数,有没有办法做到这一点?让我们说类似于:

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

或者通过某种转换或方法命名。如:

 execute(foo, foo::doSomething, myParams)

我怀疑在没有一些技巧的情况下这在 Kotlin 中是可能的。可能的解决方案是反射 API 和代码生成。

使用反射的示例:

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)
}

它应该适用于静态函数、成员函数和扩展函数。它可能会在一些罕见的情况下失败。您可能应该添加一些错误处理,例如检查参数是否匹配。

它在 JVM 以外的任何东西上都不起作用,因为反射在其他目标上仍然非常有限。

另外,我对这个不安全的转换不是很确定。我认为它不会失败,但我对此不是 100% 确定。

更新:

我们可以通过将函数转换为扩展来让它变得更有趣 operator invoke:

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

然后我们可以像这样将它与任何函数一起使用:

(foo::doSomething)(myParams)

我不确定这是否是个好主意,因为它比显式调用效用函数更令人困惑。