属性包括/排除Kotlin数据类
假设我只想要在生成的equals和hashCode实现中包含一个或两个字段(或者可能排除一个或多个字段)。 对于一个简单的类,例如:
data class Person(val id: String, val name: String)
Groovy有这样的:
@EqualsAndHashCode(includes = 'id')
龙目岛有这样的:
@EqualsAndHashCode(of = "id")
在Kotlin做这个的惯用方式是什么?
我的方法到目前为止
data class Person(val id: String) { // at least we can guarantee it is present at access time var name: String by Delegates.notNull() constructor(id: String, name: String): this(id) { this.name = name } }
只是感觉错了,虽然…我真的不希望name
是可变的,额外的构造函数定义是丑陋的。
不幸的是,这个解决方案不再有效,我还没有(还)这个问题的另一个好主意。
自动生成的函数只使用在主构造函数中声明的属性(带有val
或var
参数)。 所以你可以写:
data class Person(val id: String, name: String) { val name: String = name }
更多信息请参阅关于数据类的参考。
这是一个有点创意的方法:
data class IncludedArgs(val args: Array) fun includedArgs(vararg args: Any) = IncludedArgs(args) abstract class Base { abstract val included : IncludedArgs override fun equals(other: Any?) = when { this identityEquals other -> true other is Base -> included == other.included else -> false } override fun hashCode() = included.hashCode() override fun toString() = included.toString() } class Foo(val a: String, val b : String) : Base() { override val included = includedArgs(a) } fun main(args : Array) { val foo1 = Foo("a", "b") val foo2 = Foo("a", "B") println(foo1 == foo2) //prints "true" println(foo1) //prints "IncludedArgs(args=[a])" }
我已经使用这种方法。
data class Person(val id: String, val name: String) { override fun equals(other: Person) = EssentialData(this) == EssentialData(other) override fun hashCode() = EssentialData(this).hashCode() override fun toString() = EssentialData(this).toString().replaceFirst("EssentialData", "Person") } private data class EssentialData(val id: String) { constructor(person: Person) : this(id = person.id) }
我也不知道Kotlin(1.1)中的“idomatic方式”是这样做的…
我结束了重写equals
和hashCode
:
data class Person(val id: String, val name: String) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other?.javaClass != javaClass) return false other as Person if (id != other.id) return false return true } override fun hashCode(): Int { return id.hashCode() } }
没有“更好”的方法吗?