Когда именно ключевое слово оператора требуется в Kotlin?
на 14-й Котлин Коан при перегрузке оператора я был удивлен, когда после решения я просмотрел ответ и увидел, что operator
модификатор был не требуются compareTo
способ:
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) : Comparable<MyDate> {
override fun compareTo(other: MyDate) = when {
year != other.year -> year - other.year
month != other.month -> month - other.month
else -> dayOfMonth - other.dayOfMonth
}
}
на перегрузка оператора docs связанный с упражнением явно говорит:
функции которым операторам перегрузки нужно быть маркированным с оператором модификатор.
так что происходит здесь? Почему этот код компилируется? Когда именно operator
требуются?
2 ответов
почему этот код компилируется?
это компилируется, потому что переопределенный метод интерфейса,Comparable<T>.compareTo
, и an operator fun
.
/**
* Compares this object with the specified object for order. Returns zero if this object is equal
* to the specified [other] object, a negative number if it's less than [other], or a positive number
* if it's greater than [other].
*/
public operator fun compareTo(other: T): Int
поскольку функция переопределяет это, она также является функцией оператора.
когда именно
operator
требуются?
operator
вообще требуется, когда вы хотите иметь возможность использовать функцию, как если бы это был оператор, так как использование операторов просто компилируется для вызовов функций (за исключением примитивных типов и т. д.)
то есть foo += bar
, например, эквивалентно foo.plusAssign(bar)
, foo[bar] = baz
эквивалентно foo.set(bar, baz)
, etc.
лично я предпочитаю задание operator
везде, где это возможно, даже если это не требуется, для удобства чтения причинам.
если MyDate
были не a Comparable
, а вы опустили operator
модификатор, сравнивая две даты через <
, >
, <=
или >=
не будет компилироваться.
я не смог найти ничего в спецификация несмотря на это,. Однако в полиморфном смысле это имеет смысл-почему вы должны уметь писать a < b
где типа a
и b
are Comparable
s, но не тогда, когда они MyDate
? Поскольку вы не сможете удалить "оператор-Несс" этой функции, это имеет смысл, что operator
должен быть наследуемым от метода суперкласса.
Kotlin имеет множество функций, которые включены через particular конвенций. Они могут быть идентифицированы с помощью operator
ключевое слово. Примеры диапазоны, перегрузки операторов, операторы индекса, деструктурируется заявления и многое другое.
если мы хотим сравнить два объекта в Java, для сортировки, например, мы реализуем Comparable
интерфейс с compareTo
метод. Это также делается в Kotlin, но с гораздо лучшей поддержкой и синтаксисом стенографии. Если вы реализуете этот метод в классе, вы можете использовать все хорошие операторы, такие как <
, <=
, >
, >=
С этим классом из коробки. Эти операторы переводятся на соответствующие вызовы compareTo
компилятором:
obj1 > obj2
⇒ obj1.compareTo(obj2) > 0
метод интерфейса compareTo
на Comparable
уже определяет operator
ключевое слово, что делает его избыточным, чтобы добавить ключевое слово в свой собственный реализация.
в вашем примере operator
ключевое слово не является обязательным, так как переопределенный метод уже определяет его.