运算符重载及其他约定
一.重载算术运算符
kotlin限制了运算符重载的类别
1.重载二元算术运算
表达式 | 函数名 |
---|---|
a * b | times |
a / b | div |
a % b | mod |
a + b | plus |
a - b | minus |
data class Point(val x : Int, val y : Int){
operator fun plus(other : Point) : Point{
return Point(x + other.x, y + other.y)
}
}
Point(10,20) + Point(20,30) = Point(30,50)
定义运算符的时候,不要求两个运算数是相同的类型
operator fun Point.times(scale :Double) : Point{
return Point((x * scale).toInt(), (y * scale).toInt())
}
<注意>kotlin并不支持交换性,上述代码只支持Point Double,不支持Double Point\
2.重载复合赋值运算符
诸如+=运算会被替换为plus运算或者plusAssign运算
当两个函数都定义且适用时,编译器会报错
3.重载一元运算符
表达式 | 函数名 |
---|---|
+ a | unaryPlus |
- a | unaryMinus |
! a | not |
++ a ; a ++ | inc |
– a ; a– | dec |
二.重载比较运算符
1.equals
在kotlin中使用==运算符,则将会被转换为equals方法的调用
a == b 就相当于 a?.equals(b) ?: (b == null)
=== 为恒等运算符,对应于Java的= =运算符,用于比较是否是同一个对象
2.compareTo
两个对象的比较被转换成conpareTo函数的调用,然后结果与0进行比较
a >= b 就相当于 a.compareTo(b) >= 0
三.集合与区间的约定
使用下标运算符读取元素会被转换成get运算符方法的调用,写入元素将调用set
operator fun Point.get(index : Int) : Int{
return when(index){
0 -> x
1 -> y
else -> throw Exception("")
}
}
val p = Point(10,20)
p[0] => 10
p[1] => 20
即x[a, b] = x.get(a, b)
同理,对于set来讲
x[a, b] = c => x.set(a, b, c)
in运算符会调用contains函数
..运算符调用rangeTo函数
for循环中使用in运算符相当于调用iterator函数
四.解构声明和组件函数
要在解构声明中初始化每个变量,将调用名称为componentN的函数,其中N为声明中变量的位置。
对于数据类,编译器为每个在主构造方法中声明的属性生成一个compenentN函数,对于非数据类需要手动声明
class Point(val x : Int, val y : Int){
operator fun component1() = x;
operator fun component2() = y;
}
标准库只允许使用此语法来访问一个对象的前五个元素
五.重用属性访问的逻辑:委托属性
通过 by lazy实现惰性初始化
通过by运算符,右边只要是能都被编译器用正确的参数类型来调用setValue和getValue的对象即可
这一部分 《kotlin实战》 中讲的不够清晰,还需要再学习一下。