Documentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
An operator function in Kotlin is a function declared with the operator modifier that provides a custom implementation for a predefined language operator. This mechanism, known as operator overloading, allows instances of user-defined types to be manipulated using standard symbolic operators (such as +, ==, >, or []) by mapping those symbols to specific, statically resolved function calls.
Syntax
An operator function is defined using the operator keyword, followed by a strictly predefined function name that corresponds to the target operator.
operator fun <FunctionName>(<parameters>): <ReturnType> {
// Implementation
}
Core Mechanics
Kotlin does not allow the creation of custom operator symbols. Instead, it relies on a desugaring process during compilation. When the compiler encounters a supported operator, it translates the symbolic expression into a standard method invocation targeting the corresponding operator function.
For example, the binary expression a + b is translated by the compiler into a.plus(b).
Rules and Constraints
- Explicit Modifier: The
operator keyword is mandatory. If a function is named plus but lacks the operator modifier, it cannot be invoked using the + symbol; it can only be called via standard dot-notation (a.plus(b)).
- Predefined Naming: The function name must exactly match the Kotlin specification for the desired operator (e.g.,
plus, get, compareTo).
- Scope: Operator functions must be declared either as member functions within a class or as extension functions.
- Arity: The number of parameters is dictated by the specific operator type. Unary arithmetic operators take no parameters, and binary arithmetic operators take exactly one parameter. However, indexed access (
get, set) and invocation (invoke) operators can take an arbitrary number of parameters.
- Overloading: Operator functions can be overloaded for the same symbol by providing different parameter types, similar to standard functions.
- The
equals Exception: The equality operator (==) is a strict exception to the scope and overloading rules. It must be declared as a member function overriding Any.equals(other: Any?). Extension functions for equals are ignored by the compiler, and it cannot be overloaded with custom parameter types.
Operator to Function Mappings
Below are the categories of operators and their corresponding compiler translations.
Unary Prefix Operations
| Expression | Translated Function Call |
|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
Increments and Decrements
Unlike simple method calls, inc() and dec() must return a value, which the compiler then assigns back to the variable. The compiler automatically handles the temporary variables required to support prefix vs. postfix return semantics.
| Expression | Translated Assignment |
|---|
a++ / ++a | a = a.inc() |
a-- / --a | a = a.dec() |
Arithmetic Binary Operations
| Expression | Translated Function Call |
|---|
a + b | a.plus(b) |
a - b | a.minus(b) |
a * b | a.times(b) |
a / b | a.div(b) |
a % b | a.rem(b) |
Augmented Assignment Operations
For augmented assignments, the compiler first checks for the specific Assign function (e.g., plusAssign). If it is not available, it falls back to the standard binary operator and assigns the result back to the variable (e.g., a = a.plus(b)), provided the variable is mutable.
Ambiguity Rule: If both the augmented assignment function (e.g., plusAssign) and the corresponding binary function (e.g., plus) are defined and applicable to a mutable variable, the compiler does not fall back; instead, it reports an ambiguity error.
| Expression | Translated Function Call |
|---|
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
a %= b | a.remAssign(b) |
Equality and Inequality Operations
Equality operators are translated to the equals function, incorporating null-safety checks under the hood.
| Expression | Translated Function Call |
|---|
a == b | a?.equals(b) ?: (b === null) |
a != b | !(a?.equals(b) ?: (b === null)) |
Comparison Operations
All comparison operators translate to calls to compareTo, which must return an Int.
| Expression | Translated Function Call |
|---|
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |
Range Operations
| Expression | Translated Function Call |
|---|
a..b | a.rangeTo(b) |
a..<b | a.rangeUntil(b) |
Collection and Access Operations
| Expression | Translated Function Call |
|---|
a in b | b.contains(a) |
a !in b | !b.contains(a) |
a[i] | a.get(i) |
a[i, j] | a.get(i, j) |
a[i] = b | a.set(i, b) |
a[i, j] = b | a.set(i, j, b) |
Invocation
| Expression | Translated Function Call |
|---|
a() | a.invoke() |
a(i) | a.invoke(i) |
a(i, j) | a.invoke(i, j) |
Implementation Examples
Operator functions can be implemented as members of a class or as extensions to existing classes.
Member Operator Function:
class Matrix(val data: List<Int>, val numCols: Int) {
// Maps to the '+' operator
operator fun plus(other: Matrix): Matrix {
val newData = this.data.zip(other.data) { a, b -> a + b }
return Matrix(newData, this.numCols)
}
// Maps to the '[]' access operator (multiple parameters allowed)
operator fun get(row: Int, col: Int): Int {
// Implementation for accessing a flattened 2D structure
return data[row * numCols + col]
}
}
Extension Operator Function:
class Vector(val x: Int, val y: Int)
// Maps to the unary '-' operator
operator fun Vector.unaryMinus(): Vector {
return Vector(-this.x, -this.y)
}
// Maps to the '()' invoke operator
operator fun Vector.invoke(multiplier: Int): Vector {
return Vector(this.x * multiplier, this.y * multiplier)
}
Master Kotlin with Deep Grasping Methodology!Learn More