Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equals overloading in Kotlin

Tags:

kotlin

I was trying to overload compareTo and equals operators for my class.

There is no problem with compare operator. It works well both as member and as an extension function.

The equals operator must be a member and override equals fun.

class MyClass {
    companion object {
        private val NUMBER: Int = 5

        operator fun compareTo(value: Int) = NUMBER - value

        override operator fun equals(other: Any?) =
                when (other) {
                    is Int -> NUMBER == other
                    else -> throw Exception("")
                }
    }
}

fun test() {
    if (MyClass < 10) {
        //ok
    }

    //Operator '==' cannot be applied to 'MyClass.companion' and kotlin.Int
    if (MyClass == 5) {
    }
}

Edit: How to overload '==' properly?

like image 758
IvBaranov Avatar asked Apr 07 '16 15:04

IvBaranov


1 Answers

Defining equals and hashCode is considered somewhat useless on object declarations that have no explicit supertype, according to this issue. Probably correct equals+hashCode implementations on objects have few use cases.

There's even an IDE inspection that shows a warning when you try to do so:

IDE warning screenshot
The warning is not there when the object has a declared supertype.

However, I don't think that some technical reason stops Kotlin from resolving the overloaded operator, and the whole behaviour is strange, so I filed an issue in Kotlin issue tracker.

As for now (Kotlin 1.0.2 EAP), even with declared supertype you can only check object's equality with instances of exactly the same declared type which it has as a supertype:

object SomeObject : List<Int> by listOf() { ... }
SomeObject == listOf(1, 2, 3) // OK
SomeObject == arrayListOf(1, 2, 3) // not resolved (why?)

object MyObject : Any() { ... }
MyObject == 1 // error
MyObject == 1 as Any // OK o_O

object AnotherObject { ... }
AnotherObject == 1 as Any // works! Probably Any is supertype here

As to defining equals as an extension function: no, you can't do it because extensions are resolved statically and are shadowed by members (there's a similar question about toString).

like image 157
hotkey Avatar answered Sep 20 '22 18:09

hotkey