有没有办法在数据 class 构造时转换 属性 的值?
Is there any way to transform the value of a property at data class construction time?
创建数据时 class 我经常发现我想要转换其中一个属性,通常是对其进行规范化或制作防御性副本。例如,这里我希望 productCode
始终为小写:
data class Product(val productCode: String)
我尝试添加一个 init
块,希望 Kotlin 足够聪明,让我手动处理构造函数参数对 属性:[=20 的赋值=]
data class Product(val productCode: String) {
init {
this.productCode = productCode.toLowerCase()
}
}
但它将此视为重新分配。
我宁愿不必手动编写 equals
/hashCode
/toString
/copy
并且 IDE 生成的方法并不是真的好多了。
有什么方法可以转换数据中的构造函数参数class?
没有。为了使 equality 和 toString 起作用,属性需要位于 the primary constructor.
中
但是,您可以创建一个工厂方法:
data class Product private constructor(val productCode: String) {
companion object Factory {
fun create(productCode: String) : Product {
return Product(productCode.toLowerCase())
}
}
}
通过使构造函数 private
强制使用此 create
方法。
如果你想获得'hacky',你可以假装你仍在调用构造函数,方法是将create
重命名为invoke
并使其成为 operator
函数:
data class Product private constructor(val productCode: String) {
companion object {
operator fun invoke(productCode: String): Product {
return Product(productCode.toLowerCase())
}
}
}
调用 Product("foo")
将调用 invoke
方法。
注:构造函数仍然通过copy
方法暴露,见https://youtrack.jetbrains.com/issue/KT-11914
怎么样
sealed class Product {
abstract val productCode: String
private data class Product(override val productCode: String) : your.package.Product()
companion object {
operator fun invoke(productCode: String): your.package.Product =
Product(productCode.toLowerCase())
}
}
没有暴露copy
的data class
的所有优点。否定的是必须额外重复 属性 个名字。
创建数据时 class 我经常发现我想要转换其中一个属性,通常是对其进行规范化或制作防御性副本。例如,这里我希望 productCode
始终为小写:
data class Product(val productCode: String)
我尝试添加一个 init
块,希望 Kotlin 足够聪明,让我手动处理构造函数参数对 属性:[=20 的赋值=]
data class Product(val productCode: String) {
init {
this.productCode = productCode.toLowerCase()
}
}
但它将此视为重新分配。
我宁愿不必手动编写 equals
/hashCode
/toString
/copy
并且 IDE 生成的方法并不是真的好多了。
有什么方法可以转换数据中的构造函数参数class?
没有。为了使 equality 和 toString 起作用,属性需要位于 the primary constructor.
中但是,您可以创建一个工厂方法:
data class Product private constructor(val productCode: String) {
companion object Factory {
fun create(productCode: String) : Product {
return Product(productCode.toLowerCase())
}
}
}
通过使构造函数 private
强制使用此 create
方法。
如果你想获得'hacky',你可以假装你仍在调用构造函数,方法是将create
重命名为invoke
并使其成为 operator
函数:
data class Product private constructor(val productCode: String) {
companion object {
operator fun invoke(productCode: String): Product {
return Product(productCode.toLowerCase())
}
}
}
调用 Product("foo")
将调用 invoke
方法。
注:构造函数仍然通过copy
方法暴露,见https://youtrack.jetbrains.com/issue/KT-11914
怎么样
sealed class Product {
abstract val productCode: String
private data class Product(override val productCode: String) : your.package.Product()
companion object {
operator fun invoke(productCode: String): your.package.Product =
Product(productCode.toLowerCase())
}
}
没有暴露copy
的data class
的所有优点。否定的是必须额外重复 属性 个名字。