Kotlin:如何使用变量指定命名参数?
假设我有两种方法:Kotlin:如何使用变量指定命名参数?,kotlin,Kotlin,假设我有两种方法: private fun method1(a: A): A { return a.copy(v1 = null) } private fun method2(a: A): A { return a.copy(v2 = null) } 我可以写一些类似于: private fun commonMethod(a: A, variableToChange: String): A { retur
private fun method1(a: A): A {
return a.copy(v1 = null)
}
private fun method2(a: A): A {
return a.copy(v2 = null)
}
我可以写一些类似于:
private fun commonMethod(a: A, variableToChange: String): A {
return a.copy($variableToChange = null)
}
换句话说,我可以使用变量引用命名参数吗?如果我正确理解您试图归档的内容,我建议将setter传递给该方法,例如
fun <A> changer (a: A, setter: (a: A) -> Unit ) {
// do stuff
setter(a)
}
这就是您要寻找的吗?使用反射解决此问题的可能方法是:
inline fun <reified T : Any> copyValues(a: T, values: Map<String, Any?>): T {
val function = a::class.functions.first { it.name == "copy" }
val parameters = function.parameters
return function.callBy(
values.map { (parameterName, value) ->
parameters.first { it.name == parameterName } to value
}.toMap() + (parameters.first() to a)
) as T
}
我不相信有没有不使用reflection的方法可以做到这一点我也不相信……你可以看看这个@Daniel谢谢,我想这是使用reflection的最接近的可能性。假设目的是制作一个精确的副本,然后相对于原始字段更改一个字段,这就可以了。包装器方法将隐藏setter单元逻辑。是的,这是我想要做的,但问题是我想要更改的变量可以是val。因此,唯一的机会是复制对象,用命名参数替换变量。您可以让setter函数返回类型为a的值,这只会导致重复复制代码,我想这是您想要避免的。基本上,使用这个答案会产生比OP初始展开版本更多的代码:“是的,它可能会工作,但我担心我想避免大规模重构。如果我更改变量的签名,可能会引起同事的许多问题
data class Person (
val name: String,
val age: Int,
val foo: Boolean
)
fun main() {
var p = Person("Bob", 18, false)
println(p)
p = copyValues(p, mapOf(
"name" to "Max",
"age" to 35,
"foo" to true
))
println(p)
}
// Person(name=Name, age=15, foo=false)
// Person(name=Max, age=35, foo=true)