指定要在数据类中复制的字段 - Kotlin

kc_*_*dev 2 kotlin

有没有办法copy通过将变量名作为函数中的参数传递来指定要复制的字段?这是一个例子来说明我的意思。假设我们有以下内容:

val myData = User()

data class User(
    val firstName: String = "",
    val lastName: String = "",
    val email: String = ""
)
Run Code Online (Sandbox Code Playgroud)

我想做的是创建一个执行以下操作的函数:

fun update(fieldToBeUpdated: String, value: String) {
    myData.update {
        it.copy(fieldToBeUpdated = value)
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这是行不通的,因为编译器说

找不到具有此名称的参数:fieldToBeUpdated

有谁知道如何实现这一点,或者这在 Kotlin 中是不可能的?

Joã*_*ias 9

这是可能的,但并不漂亮。首先要确保将kotlin-reflect依赖项添加到您的pom.xml

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-reflect</artifactId>
    <version>your-kotlin-version</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

然后您将需要一些反射功能来实现这一点。按照以下几行应该可以解决问题:

import kotlin.reflect.full.instanceParameter
import kotlin.reflect.full.memberFunctions

fun main(args: Array<String>) {
    val myData = User()

    println(myData)
    println(myData.update("firstName", "Test"))
}

fun User.update(fieldToBeUpdated: String, value: String): User {
    val copy = this::class.memberFunctions.first { it.name == "copy" }
    val instanceParameter = copy.instanceParameter!!
    val parameterToBeUpdated = copy.parameters.first { it.name == fieldToBeUpdated }
    return copy.callBy(mapOf(instanceParameter to this, parameterToBeUpdated to value)) as User
}

data class User(val firstName: String = "",
                val lastName: String = "",
                val email: String = "")
Run Code Online (Sandbox Code Playgroud)