Skip to main content
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.

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

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.

Arithmetic Binary Operations

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.

Equality and Inequality Operations

Equality operators are translated to the equals function, incorporating null-safety checks under the hood.

Comparison Operations

All comparison operators translate to calls to compareTo, which must return an Int.

Range Operations

Collection and Access Operations

Invocation

Implementation Examples

Operator functions can be implemented as members of a class or as extensions to existing classes. Member Operator Function:
Extension Operator Function:
Tired of Poor Kotlin Skills? Fix That With Deep Grasping!Learn More