Kotlin
中的运算符重载:在我们自己定义的类中,可以为一组预定义的运算操作提供自己的实现。这些运算符有固定的符号表示(*或+),以及固定的函数名称。为了实现这一个运算符,我们以固定名称的方式提供了成员函数或者扩展函数。比如如下类型:二目运算中靠左元素的数据类型以及一目运算的参数类型。重载符号函数必须使用关键字operator
标识。
未来,我们会更加规划运算符重载。
一元运算符
一元前缀运算符
表达式 | 翻译成 |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
以+a
为例,解释下编译器的处理过程
- 确定
a
的类型,以T
举例 - 查找
T
类中是否含有unaryPlus
函数,该方法用operator
,扩展函数或者成员函数都可以 - 如果该函数缺失或者有歧义,则编译失败
- 如果该函数存在,并返回类型
R
,则该表达式类型为R
注意:基本类型的这些运算符都进行了优化,不会增加调用的开销
举个栗子
data class Point(val x: Int, val y: Int)
operator fun Point.unaryMinus() = Point(-x, -y)
fun main(args: Array<String>) {
val point = Point(10, 20)
println(-point) // prints "(-10, -20)"
}
Point
数据类有一个扩展函数unaryMinus()
,所以当我们执行-point
实际调用point.unaryMinus()
,所以输出结果:
Point(x=-10, y=-20)
递增和递减
表达式 | 翻译成 |
---|---|
a++ | a.inc() |
a– | a.dec() |
以
a++
为例
- 确定a的类型,以
T
表示 - 在T对象实例的成员函数和扩展函数中查找是否含有
inc()
函数。 - 检查函数返回类型是否是
T
的子类。
计算过程
- 将
a
的值存储到临时变量a0
- 将
a.inc()
的计算结果赋值给a
- 将
a0
的值作为结果返回
二目运算
算术运算
表达式 | 翻译成 |
---|---|
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)(1.1中加入), a.mod(b) (1.0,1.1中已废弃) |
a..b | a.rangeTo(b) |
举个栗子a+b
fun main(args: Array<String>) {
val counter = Counter(1)
println(counter + 3)
}
data class Counter(var dayIndex: Int) {
operator fun plus(increment: Int): Counter {
return Counter(dayIndex + increment)
}
}
执行结果:
Counter(dayIndex=4)
in
操作
表达式 | 翻译成 |
---|---|
a in b | b.contains(a) |
a !in b | !b.contains(a) |
索引操作
表达式 | 翻译成 |
---|---|
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() | 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) |
增强作业
表达式 | 翻译成 |
---|---|
a += b | a.plusAssign(b) |
a -= b | a.minusAssign(b) |
a *= b | a.timesAssign(b) |
a /= b | a.divAssign(b) |
a %= b | a.modAssign(b) |
举个栗子 a+=b
- 首先判断
plusAssign
是否存在
- 如果存在
- 如果
plus()
和plusAssign()
,有歧义,报错 - 确保
plusAssign()
返回Unit
,否则报错
- 如果
- 如果不存在,变换为a=a+b
- 如果存在
相等和不等操作
表达式 | 翻译成 |
---|---|
a == b | a?.equals(b) ?: (b === null) |
a != b | !(a?.equals(b) ?: (b === null)) |
比较操作
表达式 | 翻译成 |
---|---|
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |