假设我有一个包含三个属性的数据类:
data class Product(
val id: Int,
val name: String,
val manufacturer: String)
如果我理解正确,Kotlin将使用所有三个属性生成equals()
和hashCode()
,如下所示:
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
val that = other as Product?
return id == that.id &&
name == that!!.name &&
manufacturer == that.manufacturer
}
override fun hashCode(): Int {
return Objects.hash(id, name, manufacturer)
}
那么如果我不想在id
和equals()
中使用hashCode()
该怎么办?有没有办法告诉Kotlin在生成这些函数时忽略某些属性? toString()
和compareTo()
怎么样?
答案 0 :(得分:3)
对于数据类,使用在主构造函数中声明的所有属性生成这些函数。来自official documentation:
编译器自动从所有成员派生以下成员 在主构造函数中声明的属性:
- equals()/ hashCode()对,
- toString()形式"用户(姓名=约翰,年龄= 42)",
- componentN()函数对应于中的属性 他们的声明顺序,
- copy()函数(见下文)。
如果您希望不将实施的属性考虑在内,您必须将其移出主要构造函数,或者自己实现这些功能。
有关类似问题的更多讨论here。
答案 1 :(得分:1)
对我来说效果很好的解决方案是将元数据与数据分开。 e.g:
data class Entity<out T>(val id: Int, val data: T)
data class Person(val name: String, val manufacturer: String)
用法:
val e1 = Entity(1, Person("Mickey", "Disney"))
val e2 = Entity(2, Person("Mickey", "Disney"))
val e3 = Entity(3, Person("Donald", "Disney"))
e1 == e2
// false
e1.data == e2.data
// true
e2.data == e3.data
// false
答案 2 :(得分:0)
来自文档:
请注意,编译器仅使用主构造函数内定义的属性来自动生成函数。要从生成的实现中排除属性,请在类体内声明它。
您的示例必须如下所示:
data class Product(
val name: String,
val manufacturer: String) {
val id: Int
}
有关详细信息,请查看:https://kotlinlang.org/docs/reference/data-classes.html#properties-declared-in-the-class-body