liveBook · Manning

Operator modifier

As explained in Kotlin in Action, 2E

The operator modifier is a Kotlin declaration modifier that permits a function to implement a predefined operator convention.

The operator modifier marks a function as the implementation of a predefined Kotlin operator convention. It makes the intent explicit: a function named plus can be called with +, while a function with an accidentally matching name cannot. Kotlin supports a limited operator set rather than arbitrary custom symbols. section 9.1.1

Listing 9.1 Defining the plus operator
data class Point(val x: Int, val y: Int) {
    operator fun plus(other: Point): Point {     #1
        return Point(x + other.x, y + other.y)   #2
    }
}
 
fun main() {
    val p1 = Point(10, 20)
    val p2 = Point(30, 40)
    println(p1 + p2)                             #3
    // Point(x=40, y=60)
}

A member function marked operator lets Point values use the + expression; Kotlin translates the expression to a plus function call. section 9.1.1

The declaration form is constrained by the convention being implemented:

  • Define the function as a member or extension, then mark it operator. section 9.1.1
  • Use the predefined function name: plus, minus, times, div, mod, unaryPlus, unaryMinus, not, inc, or dec. section 9.1.3 section 9.1.1
  • Respect the convention’s signature; unary operators take no arguments, while binary operators can use different operand and return types. section 9.1.3 section 9.1.1
  • Expect standard operator precedence, even for user-defined types; use infix functions when a custom function-call shape is needed. section 9.1.1

Incrementing a Java standard-library value

An extension operator can add ++ behavior to BigDecimal: operator fun BigDecimal.inc() = this + BigDecimal.ONE. With var bd = BigDecimal.ZERO, bd++ prints 0 and then leaves bd as 1; ++bd prints 2. section 9.1.3

Listing 9.22 ObservableProperty as a property delegate
import kotlin.reflect.KProperty

class ObservableProperty(var propValue: Int, val observable: Observable) {
 operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = propValue

 operator fun setValue(thisRef: Any?, prop: KProperty<*>, newValue: Int) {
     val oldValue = propValue
     propValue = newValue
     observable.notifyObservers(prop.name, oldValue, newValue)
   }
}

Delegated properties use the same modifier on getValue and setValue, allowing the compiler to connect property access with a delegate. section 9.5.3

How Kotlin in Action, 2E covers it

How deep it goes
Explains declaration forms, name mappings, signatures, translation, precedence, and delegation, but not arbitrary custom operators.
Examples
Uses Point arithmetic, unary negation, BigDecimal incrementing, equality checks, and observable delegated properties.
What it assumes
Assumes basic Kotlin functions and classes while teaching operator-to-function translation and delegation signatures through examples.
What you can do after
Builds Kotlin member and extension functions that support predefined operators and delegated-property access.
How it connects
Connects operator overloading with extension functions, infix functions, equality, delegated properties, and Java interoperability.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.