Reputation: 3973
Here an equals overloading
class MyClass {
...
val string: String = ...
override operator fun equals(other: Any?): Boolean {
if (other != null) else { return false }
if (other is MyClass && string == other.string) { return true }
if (other is String && string == other) { return true }
return false
}
...
}
The idea is to be able to compare:
myClass1 = MyClass("ABCDEF")
myClass2 = MyClass("ABC123")
myClass1 == fsPath2 >> false
or
myClass1 == "ABC123" >> false
But the precompiled says: Operator '==' cannot be applied to 'MyClass' and 'String'
Any idea?
Upvotes: 2
Views: 338
Reputation: 18557
I'm afraid this can't work the way you want.
In order for equality to behave the way everyone expects, it has a very specific contract. (The docs for the Kotlin Any.equals() method spell out all the necessary conditions, and the docs for the Java Object.equals() method have a bit more info.)
One of the conditions is that the equality relation must be reversible: a == b
if and only if b == a
. (In technical terms, the relation must be symmetric.)
But that's not true of your implementation:
myClass1.equals("ABCDEF")
returns true (from MyClass
's implementation of equals()
), but"ABCDEF".equals(myClass1)
returns false (from calling String
's implementation)A system class like String
doesn't know about your class, and there's no way to change its equals()
implementation so it does. So unfortunately there's no way to treat it as equal, without breaking the contract.
(You can probably imagine some of the subtle bugs that could cause: for example, a Set could hold both of those objects, or just one, depending on the order they happened to be added in…)
The compiler error you're getting is an indirect result of this: assuming the equals()
contract holds, unrelated classes are never going to be treated as equal, so the compiler won't even let you try to compare them that way.
Because of the strict contract, you need to take great care when implementing equals()
; as well symmetry, it's easy to break transitivity and/or consistency, and you need to override hashCode()
to match. See for example these articles. (And even if you control both classes, it's still surprisingly tricky to get equality working between them; this article explains the issues rather well.)
Upvotes: 5