Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Kotlin中重写等于_Kotlin - Fatal编程技术网

在Kotlin中重写等于

在Kotlin中重写等于,kotlin,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) &&

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))
}
编译器对象
CS(“hello”)=“hello”
as:Operator'==”不能应用于“CS”和“String”。它与任何
CS(“hello”)==“hello”或
CS(“hello”).equals(“hello”)
一样没有问题,这两者都可以工作


我做错了什么?

@Michael在评论中提到此运算符是有效的,因此您可以转到下面的答案:

我认为,您得到的错误可能与Kotlin在推断数据类型方面存在问题有关。您提供了
Any
类型作为
equals(…)
方法的参数,并将其与您的类(
this
)进行比较。也许你可以试着用这样的方式来表达:

this == (other as String)


我不确定这是不是正确的方法,但也许这会给你一个提示。

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

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

但是您的实现没有通过这个测试,因为
CS(“abc”).equals(“abc”)
返回
true
,而
“abc”).equals(CS(“abc”)
false
。这是因为您的类知道
CharSequence
,例如
String
,但
String
不知道您的类

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

因此,
equals()
的大多数实现倾向于按照以下思路工作:

override fun equals(other: Any?)
    = (other is ThisClass)
    && field1 == other.field1
    && field2 == other.field2
    // ...

正如我所说,我不知道Kotlin编译器为什么对你的情况抱怨。可能是它发现了这个问题的某些方面,也可能是一些不相关的方面。但我认为你无法以一种平等性检查可以满足你需要的方式修复你的程序,因此,也许最好将此作为一个提示,尝试一种稍微不同的方法

如果操作两侧的类型已知且彼此不同,Kotlin中的
==
运算符将不起作用。
例如:

3 == "Hello"
true == 5.0
// and so on
将给出编译错误,因为编译器推断操作数是不同类的实例,因此不能相等

唯一的例外是,如果运算符的一侧是另一侧的子类:

open class A
class B: A()
class C: A()

val c = C()
val b = B()
val a = A()

c == b
c == a // good
a == b // also good
在这种情况下,
c==b
将给出一个编译错误,而其他两个操作则不会


这就是为什么当您将操作的一侧强制转换为
Any
时,它不再给出错误,因为所有内容都是
Any

的子类型。“我不确定triple equals运算符===在Kotlin中是否可用”。很高兴认识@Michael。谢谢谢谢Piotr,但这不是我遇到问题的
equals
中的代码。我希望
CS(“hello”)==“hello”
被解释为
CS(“hello”).equals(“hello”)
——这在显式编写时有效。因此,“hello”属于Any的子类。它是,但与JS的含义完全不同。“override get/length in interface CharSequence”最好使用委托:
:CharSequence by sequence
。谢谢,平等应该是一种等价关系,这是有道理的——在这种情况下,我可能会觉得很烦人。我的原始类(java)在字符串的一部分(当然使用了.Authals[])提供了一个“视图”,所以它都运行得很顺利。C++在工作日内工作。一只老狗必须学会新的技巧(或者根据观点去忘记坏习惯)。.Kotlin的解决方案是有意义的。有三种类型的相等。
===
测试值是否相同,
==
测试它们是否应该被视为等效实例(以某种方式)。第三种意义是作为顺序,例如与等一起使用。
a.compareTo(b)
可能会给出零(即相等)即使
a.equals(b)
可能不会。例如,第一个可以进行大小写盲比较,而第二个可能不会。Kotlin的决定不是为a.compare(b)==0提供速记。我将使用中缀函数
isLike
open class A
class B: A()
class C: A()

val c = C()
val b = B()
val a = A()

c == b
c == a // good
a == b // also good