Kotlin maps operators to functions with fixed names: a + b calls a.plus(b), a * b calls times, a[i] calls get, x in a calls a.contains(x), and a > b becomes a.compareTo(b) > 0. Mark a member or extension operator and the symbol works on your type.
data class Money(val cents: Long) : Comparable<Money> {
operator fun plus(other: Money) = Money(cents + other.cents)
operator fun times(qty: Int) = Money(cents * qty)
override fun compareTo(other: Money) = cents.compareTo(other.cents)
override fun toString() = "$%d.%02d".format(cents / 100, cents % 100)
}
infix fun Int.copiesAt(price: Money) = price * this
fun main() {
var total = 2 copiesAt Money(2400)
total += Money(1499)
println("$total, over $50: ${total > Money(5000)}")
}$62.99, over $50: true
On a var, total += x falls back to total = total + x when there is no plusAssign. copiesAt is an infix function: a member or extension with exactly one parameter, no vararg and no default, called without a dot or parentheses, like the standard library's to in "id" to 1. Infix calls bind more loosely than arithmetic, so 2 copiesAt a + b passes a + b. Overload operators only where the meaning is obvious, and keep money in integer cents: in Double, 16.20 * 3 prints 48.599999999999994.