Перегрузка операторов
Kotlin позволяет предоставлять собственные реализации для предопределённого набора операторов типов. Эти операторы имеют предопределённое символьное представление (например, + или *) и приоритет. Чтобы реализовать оператор, предоставьте функцию-член или функцию-расширение с определённым именем для соответствующего типа. Этот тип становится типом левого операнда для бинарных операций и типом аргумента для унарных.
Чтобы перегрузить оператор, пометьте соответствующую функцию модификатором operator:
interface IndexedContainer {
operator fun get(index: Int)
}
При переопределении перегруженных операторов можно опустить operator:
class OrdersList: IndexedContainer {
override fun get(index: Int) { /*...*/ }
}
Унарные операции
Унарные префиксные операторы
Выражение |
Переводится в |
|---|---|
|
|
|
|
|
|
Эта таблица означает, что при обработке компилятором, например, выражения +a выполняются следующие шаги:
Определяется тип
a; пусть это будетT.Для получателя
Tищется функцияunaryPlus()с модификаторомoperatorи без параметров, то есть функция-член или функция-расширение.Если функция отсутствует или неоднозначна, возникает ошибка компиляции.
Если функция существует и её тип возвращаемого значения —
R, выражение+aимеет типR.
Например, вот как можно перегрузить унарный оператор минуса:
data class Point(val x: Int, val y: Int)
operator fun Point.unaryMinus() = Point(-x, -y)
val point = Point(10, 20)
fun main() {
println(-point) // prints "Point(x=-10, y=-20)"
}
Инкременты и декременты
Выражение |
Переводится в |
|---|---|
|
|
|
|
Функции inc() и dec() должны возвращать значение, которое будет присвоено переменной, к которой применена операция ++ или --. Они не должны изменять объект, к которому применена операция inc или dec.
Для разрешения оператора в постфиксной форме, например a++, компилятор выполняет следующие шаги:
Определяет тип
a; пусть это будетT.Ищет функцию
inc()с модификаторомoperatorи без параметров, применимую к получателю типаT.Проверяет, что тип возвращаемого значения функции является подтипом
T.
Вычисление выражения приводит к следующим действиям:
Сохраняется исходное значение
aво временном хранилищеa0.Результат
a0.inc()присваиваетсяa.a0возвращается как результат выражения.
Для a-- шаги полностью аналогичны.
Для префиксных форм ++a и --a разрешение выполняется аналогичным образом, а результатом будет следующее:
Результат
a.inc()присваиваетсяa.Новое значение
aвозвращается как результат выражения.
Бинарные операции
Арифметические операторы
Выражение |
Переводится в |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Для операций из этой таблицы компилятор просто разрешает выражение, указанное в столбце «Переводится в».
Ниже приведён пример класса Counter, который начинается с заданного значения и может увеличиваться с помощью перегруженного оператора +:
data class Counter(val dayIndex: Int) {
operator fun plus(increment: Int): Counter {
return Counter(dayIndex + increment)
}
}
Оператор in
Выражение |
Переводится в |
|---|---|
|
|
|
|
Для in и !in процедура аналогична, но порядок аргументов обратный.
Оператор доступа по индексу
Выражение |
Переводится в |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Квадратные скобки преобразуются в вызовы get и set с соответствующим количеством аргументов.
Оператор invoke
Выражение |
Переводится в |
|---|---|
|
|
|
|
|
|
|
|
Круглые скобки преобразуются в вызовы invoke с соответствующим количеством аргументов.
Составные операторы присваивания
Выражение |
Переводится в |
|---|---|
|
|
|
|
|
|
|
|
|
|
Для операций присваивания, например a += b, компилятор выполняет следующие шаги:
-
Если доступна функция из правого столбца:
Если также доступна соответствующая бинарная функция (то есть
plus()дляplusAssign()),aявляется изменяемой переменной, а тип возвращаемого значенияplusявляется подтипом типаa, сообщается об ошибке (неоднозначность).Проверяет, что тип возвращаемого значения —
Unit, иначе сообщает об ошибке.Генерирует код для
a.plusAssign(b).
В противном случае пытается сгенерировать код для
a = a + b(включая проверку типов: типa + bдолжен быть подтипомa).
Операторы равенства и неравенства
Выражение |
Переводится в |
|---|---|
|
|
|
|
Эти операторы работают только с функцией equals(other: Any?): Boolean, которую можно переопределить, чтобы предоставить собственную реализацию проверки равенства. Любые другие функции с тем же именем (например, equals(other: Foo)) игнорируются.
Kotlin вызывает .equals(), если ни один из операндов напрямую не сравнивается с null в выражении == и сравнение выполняется не между двумя типами с плавающей точкой. В противном случае Kotlin использует === для прямых сравнений null и сравнивает ненулевые значения с плавающей точкой по их числовому значению.
Операторы сравнения
Выражение |
Переводится в |
|---|---|
|
|
|
|
|
|
|
|
Все сравнения преобразуются в вызовы compareTo, который должен возвращать Int.
Операторы делегирования свойств
Функции-операторы provideDelegate, getValue и setValue описаны в разделе Делегированные свойства.
Инфиксные вызовы именованных функций
Пользовательские инфиксные операции можно имитировать с помощью инфиксных вызовов функций.
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/operator-overloading.html