属性包括/排除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是可变的,额外的构造函数定义是丑陋的。

不幸的是,这个解决方案不再有效,我还没有(还)这个问题的另一个好主意。


自动生成的函数只使用在主构造函数中声明的属性(带有valvar参数)。 所以你可以写:

 data class Person(val id: String, name: String) { val name: String = name } 

更多信息请参阅关于数据类的参考。

这是一个有点创意的方法:

 data class IncludedArgs(val args: Array<out Any>) 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<String>) { 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方式”是这样做的…

我结束了重写equalshashCode

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

没有“更好”的方法吗?