Skip to main content

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

  1. 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)).
  2. Predefined Naming: The function name must exactly match the Kotlin specification for the desired operator (e.g., plus, get, compareTo).
  3. Scope: Operator functions must be declared either as member functions within a class or as extension functions.
  4. 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.
  5. Overloading: Operator functions can be overloaded for the same symbol by providing different parameter types, similar to standard functions.
  6. 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

ExpressionTranslated Function Call
+aa.unaryPlus()
-aa.unaryMinus()
!aa.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.
ExpressionTranslated Assignment
a++ / ++aa = a.inc()
a-- / --aa = a.dec()

Arithmetic Binary Operations

ExpressionTranslated Function Call
a + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.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.
ExpressionTranslated Function Call
a += ba.plusAssign(b)
a -= ba.minusAssign(b)
a *= ba.timesAssign(b)
a /= ba.divAssign(b)
a %= ba.remAssign(b)

Equality and Inequality Operations

Equality operators are translated to the equals function, incorporating null-safety checks under the hood.
ExpressionTranslated Function Call
a == ba?.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.
ExpressionTranslated Function Call
a > ba.compareTo(b) > 0
a < ba.compareTo(b) < 0
a >= ba.compareTo(b) >= 0
a <= ba.compareTo(b) <= 0

Range Operations

ExpressionTranslated Function Call
a..ba.rangeTo(b)
a..<ba.rangeUntil(b)

Collection and Access Operations

ExpressionTranslated Function Call
a in bb.contains(a)
a !in b!b.contains(a)
a[i]a.get(i)
a[i, j]a.get(i, j)
a[i] = ba.set(i, b)
a[i, j] = ba.set(i, j, b)

Invocation

ExpressionTranslated 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