kotlinintermediate
Kotlin Operator Overloading
Overload operators for custom types: arithmetic, comparison, indexing, destructuring, and invoke.
kotlinPress ⌘/Ctrl + Shift + C to copy
// Vector2D with operator overloading
data class Vector2D(val x: Double, val y: Double) {
// Arithmetic operators
operator fun plus(other: Vector2D) = Vector2D(x + other.x, y + other.y)
operator fun minus(other: Vector2D) = Vector2D(x - other.x, y - other.y)
operator fun times(scalar: Double) = Vector2D(x * scalar, y * scalar)
operator fun div(scalar: Double) = Vector2D(x / scalar, y / scalar)
operator fun unaryMinus() = Vector2D(-x, -y)
// Comparison
operator fun compareTo(other: Vector2D): Int =
magnitude().compareTo(other.magnitude())
fun magnitude() = Math.sqrt(x * x + y * y)
// Destructuring (already provided by data class)
// operator fun component1() = x
// operator fun component2() = y
override fun toString() = "($x, $y)"
}
// Extension operator
operator fun Double.times(v: Vector2D) = v * this
// Matrix with index operator
class Matrix(val rows: Int, val cols: Int) {
private val data = Array(rows) { DoubleArray(cols) }
operator fun get(row: Int, col: Int): Double = data[row][col]
operator fun set(row: Int, col: Int, value: Double) { data[row][col] = value }
operator fun plus(other: Matrix): Matrix {
require(rows == other.rows && cols == other.cols)
return Matrix(rows, cols).also { result ->
for (r in 0 until rows)
for (c in 0 until cols)
result[r, c] = this[r, c] + other[r, c]
}
}
override fun toString(): String =
data.joinToString("\n") { row -> row.joinToString(", ") { "%.1f".format(it) } }
}
// Invoke operator
class Validator<T>(private val rules: List<(T) -> String?>) {
operator fun invoke(value: T): List<String> =
rules.mapNotNull { it(value) }
}
// contains operator for range-like check
data class DateRange(val start: Int, val end: Int) {
operator fun contains(day: Int) = day in start..end
}
fun main() {
// Vector operations
val v1 = Vector2D(3.0, 4.0)
val v2 = Vector2D(1.0, 2.0)
println("v1 + v2 = ${v1 + v2}")
println("v1 - v2 = ${v1 - v2}")
println("v1 * 2 = ${v1 * 2.0}")
println("2 * v1 = ${2.0 * v1}")
println("-v1 = ${-v1}")
// Destructuring
val (x, y) = v1
println("x=$x, y=$y")
// Matrix
val m = Matrix(2, 2)
m[0, 0] = 1.0; m[0, 1] = 2.0
m[1, 0] = 3.0; m[1, 1] = 4.0
println("Matrix:\n$m")
// Invoke
val validateAge = Validator<Int>(listOf(
{ if (it < 0) "Must be positive" else null },
{ if (it > 150) "Unrealistic age" else null }
))
println("Validate 25: ${validateAge(25)}")
println("Validate -5: ${validateAge(-5)}")
// contains
val vacation = DateRange(15, 25)
println("20 in vacation: ${20 in vacation}")
println("10 in vacation: ${10 in vacation}")
}Use Cases
- Mathematical libraries with natural syntax
- Domain-specific types with operations
- Indexable and callable objects
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinintermediate
Operator Overloading
Overload operators in Kotlin: arithmetic, comparison, indexing, invoke, and destructuring.
Best for: Mathematical and scientific computing
#kotlin#operators
kotlinbeginner
Null Safety — Elvis, Safe Call, and let
Master Kotlin null safety: safe calls, Elvis operator, let/also scoping, and smart casts.
Best for: Safe navigation through nullable chains
#kotlin#null-safety
kotlinbeginner
Data Classes — Copy, Destructure, and Equals
Use data classes for immutable models: auto-generated equals, hashCode, copy, and destructuring.
Best for: Immutable domain models and DTOs
#kotlin#data-class
kotlinbeginner
Extension Functions and Properties
Add methods to existing classes without inheritance: extension functions, properties, and generic extensions.
Best for: Adding utility methods to third-party types
#kotlin#extensions