Kotlin 允许为类型提供预定义的操作符实现,这些操作符具有固定的符号表示(例如 + 和 * )和固定的优先级,通过操作符重载可以将操作符的行为映射到指定的方法。为实现这样的操作符,需要为类提供一个固定名字的成员函数或扩展函数,相应的重载操作符的函数需要用 operator 修饰符标记
操作符 |
函数 |
+a |
a.unaryPlus() |
-a |
a.unaryMinus() |
!a |
a.not() |
a++ |
a.inc() |
a-- |
a.dec() |
操作符 |
函数 |
a + b |
a.plus(b) |
a - b |
a.minus(b) |
a * b |
a.times(b) |
a / b |
a.div(b) |
a % b |
a.rem(b) |
a..b |
a.rangeTo(b) |
a in b |
b.contains(a) |
a !in b |
!b.contains(a) |
a += b |
a.plusAssign(b) |
a -= b |
a.minusAssign(b) |
a *= b |
a.timesAssign(b) |
a /= b |
a.divAssign(b) |
a %= b |
a.remAssign(b) |
操作符 |
函数 |
a[i] |
a.get(i) |
a[i, j] |
a.get(i, j) |
a[i_1, ..., i_n] |
a.get(i_1, ..., i_n) |
a[i] = b |
a.set(i, b) |
a[i, j] = b |
a.set(i, j, b) |
a[i_1, ..., i_n] = b |
a.set(i_1, ..., i_n, b) |
操作符 |
函数 |
a == b |
a?.equals(b) ?: b === null |
a != b |
!(a?.equals(b) ?: b === null) |
相等操作符有一点不同,为了达到正确合适的相等检查做了更复杂的转换,因为要得到一个确切的函数结构比较,不仅仅是指定的名称
方法必须要如下准确地被实现:
operator fun equals(other: Any?): Boolean
操作符 === 和 !== 用来做身份检查(它们分别是 Java 中的 == 和 != ),并且它们不能被重载
操作符 |
函数 |
a > b |
a.compareTo(b) > 0 |
a < b |
a.compareTo(b) < 0 |
a >= b |
a.compareTo(b) >= 0 |
a <= b |
a.compareTo(b) <= 0 |
所有的比较都转换为对 compareTo 的调用,这个函数需要返回 Int 值 |
|
方法 |
调用 |
a() |
a.invoke() |
a(i) |
a.invoke(i) |
a(i, j) |
a.invoke(i, j) |
a(i_1, ..., i_n) |
a.invoke(i_1, ..., i_n) |
看几个例子
data class Point(val x: Int, val y: Int) {
//+Point
operator fun unaryPlus() = Point(+x, +y)
//Point++ / ++Point
operator fun inc() = Point(x + 1, y + 1)
//Point + Point
operator fun plus(point: Point) = Point(x + point.x, y + point.y)
//Point + Int
operator fun plus(value: Int) = Point(x + value, y + value)
//Point[index]
operator fun get(index: Int): Int {
return when (index) {
0 -> x
1 -> y
else -> throw IndexOutOfBoundsException("无效索引")
}
}
//Point(index)
operator fun invoke(index: Int) = when (index) {
0 -> x
1 -> y
else -> throw IndexOutOfBoundsException("无效索引")
}
}
fun main(args: Array<String>) {
//+Point
println("+${Point(10, -20)} = ${+Point(10, -20)}")
//Point++
var point = Point(10, -20)
println("${Point(10, -20)}++ = ${point++}")
//++Point
point = Point(10, -20)
println("++${Point(10, -20)} = ${++point}")
//Point + Point
println("${Point(10, -20)} + ${Point(10, -20)} = ${Point(10, -20) + Point(10, -20)}")
//Point + Int
println("${Point(10, -20)} + ${5} = ${Point(10, -20) + 5}")
//Point[index]
point = Point(10, -20)
println("point[0] value is: ${point[0]}")
println("point[1] value is: ${point[1]}")
//Point(index)
println("point(0) values is: ${point(0)}")
}
