在 Kotlin 中覆盖 equals

epo*_*che 18 kotlin

CS实施kotlin.CharSequence. 它的精髓在这里:

class CS  (val sequence: CharSequence = "") : CharSequence {
... override get/length in interface CharSequence 
    override fun equals(other: Any?): Boolean =
            (this === other) || ((other is String) && this.sequence.equals(other))
}
Run Code Online (Sandbox Code Playgroud)

编译器对象CS("hello") == "hello"为:运算符 '==' 不能应用于 'CS' 和 'String'。它没有问题CS("hello") == "hello" as AnyCS("hello").equals("hello")两者都有效。

我究竟做错了什么?

gid*_*dds 17

我不确定这个错误的原因,但它可能与你的方法更深层次的问题有关......

在 Kotlin(和 Java)中,该equals()方法具有相当严格的规范。一个条件是它必须是对称的:当ab不为空时,a.equals(b)必须始终给出与 相同的结果b.equals(a)

但是您的实现未能通过此测试,因为CS("abc").equals("abc")返回true, while"abc".equals(CS("ABC"))false。那是因为您的班级知道CharSequence诸如 s 之类的信息String,但String不了解您的班级。

没有简单的方法来解决这个问题。通常,允许类的实例仅等于该类的实例要安全得多。如果你同时控制这两个类,那么有很多方法可以解决这个问题,但它们非常微妙和复杂。(也许最好的解释是Martin Odersky 等人的。)

所以大多数 的实现equals()倾向于按照以下方式工作:

override fun equals(other: Any?)
    = (other is ThisClass)
    && field1 == other.field1
    && field2 == other.field2
    // ...
Run Code Online (Sandbox Code Playgroud)

正如我所说,我不知道为什么 Kotlin 编译器在你的情况下抱怨。可能是它发现了这个问题,也可能是不相关的。但是我不认为您将能够以相等检查会做您想要的方式修复您的程序,所以也许最好以此作为尝试稍微不同的方法的提示!