Kotlin 中的平等
Posted
技术标签:
【中文标题】Kotlin 中的平等【英文标题】:Equality in Kotlin 【发布时间】:2018-01-28 02:27:12 【问题描述】:我正在学习 Kotlin,具有 C++ 和 Java 背景。我期待以下内容打印true
,而不是false
。我知道==
映射到equals
。 equals
的默认实现是否不比较每个成员,即firstName
和lastName
?如果是这样,它不会看到字符串值相等(因为==
再次映射到equals
)?显然,我在 Kotlin 中还没有搞清楚与平等与身份相关的一些东西。
class MyPerson(val firstName: String, val lastName: String)
fun main(args: Array<String>)
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker"))
【问题讨论】:
【参考方案1】:您描述的默认equals
实现仅适用于数据类。不适用于从Any
继承实现的常规类,只需使对象与自身相等。
【讨论】:
所以,如果 equals 没有被常规类覆盖,它本质上与调用 === 相同。 @stdout 正是我正在寻找的答案。【参考方案2】:参照平等
Java
在 Java 中,equals
的默认实现比较变量的 reference,这就是 ==
总是所做的:
Object
类的equals
方法实现了最区分 对象上可能的等价关系;也就是说,对于任何非空 引用值 x 和 y,此方法返回true
当且仅当 x 和 y 指的是同一个对象(x == y
的值是true
)。
我们称之为“参照平等”。
科特林
在 Kotlin 中,==
被编译为 equals
,而 ===
相当于 Java 的 ==
。
结构平等
当我们想要结构而不是引用相等时,我们可以覆盖equals
,对于,这是从不默认完成的正常的 类,正如你所建议的那样。在 Kotlin 中,我们可以使用data class
,编译器会根据构造函数属性自动为其创建一个实现(阅读here)。
如果您手动覆盖equals
(反之亦然),请记住始终覆盖hashCode
,并坚持两种方法都非常严格的contracts。 Kotlin 的编译器生成的实现确实满足合同。
【讨论】:
在 kotlin 中,您可以 ctrl + click==
运算符,如果您 ctrl + 单击 equals
方法,您还将看到指向相同实现的链接。【参考方案3】:
== 表示平等
在 Java 中,您可以使用 == 来比较原始类型和引用类型。如果应用于原始类型,Java 的 == 比较值,而引用类型上的 == 比较引用。因此,在 Java 中,众所周知的做法是总是调用 equals,而众所周知的问题是忘记这样做。
在 Kotlin 中,== 是比较两个对象的默认方式:它通过在底层调用 equals 来比较它们的值。因此,如果在您的类中重写了 equals,您可以使用 == 安全地比较它的实例。对于参考比较,您可以使用 === 运算符,其工作方式与 Java 中的 == 完全相同。
class MyPerson(val firstName: String, val lastName: String)
override fun equals(other: Any?): Boolean
if (other == null || other !is MyPerson) return false
return firstName == other.firstName && lastName == other.lastName
fun main(args: Array<String>)
println(MyPerson("Charlie", "Parker") == MyPerson("Charlie", "Parker")) // print "true"
在您的情况下,MyPerson
曾经是 data class
,它自动生成通用方法的实现(toString
、equals
和 hashCode
)。
【讨论】:
以上是关于Kotlin 中的平等的主要内容,如果未能解决你的问题,请参考以下文章