第七章 运算符重载及其他约定
约定的定义比较模糊,一般说是通过调用自己代码中定义的函数,来实现特定语言结构。
在Kotlin中,这些功能与特定的函数命名相关,而不是与特定的类型绑定。
7.1 重载算术运算符
Kotlin限定了可以重载的运算符,以及需要在类中定义的对应名字的函数。
开发者是不能定义自己的运算符的。
7.1.1 重载二元算术运算
重载运算符:用operator关键字来声明对应函数。本质上就是特定名字的函数罢了。
示例:
//声明
data class Point(val x:Int,val y:Int){
operator fun plus(other:Point):Point{
return Point(x + other.x,y + other.y)
}
}
//调用
val p1 = Point(10,20)
val p2 = Point(30,40)
println(p1 + p2)
>>>>>>>
Point(x=40,y=60)
- 可重载的二元算术运算符有
| 表达式 | 函数名 |
| :— | :----|
| a*b | times |
| a/b | div |
| a%b | mod |
| a+b | plus |
| a-b | minus |
其有下面几个要点:
1.可以声明为成员函数或扩展函数。
operator fun Point.plus(other:Point):Point{
return Point(x + other.x, y + other.y)
}
2.重载的运算符,基本上和与标准数字类型的运算符有着相同的优先级。例如*、/和%的优先级高于+和-。
3.定义运算符的时候,两个运算数的类型是自由的,可以不同的。
4.返回值也是自由的,可以不同于任一运算数类型。
5.和普通函数一样,可以定义多个同名的,但参数类型不同的运算符函数。
6.Koltin运算符没有自动支持交换性,即交换运算符两边运算数是不支持的。因为其对应的是定义时的类型。
位运算
特别的,Kotlin中位运算是没有特殊运算符的。但它使用支持中缀调用语法的常规函数。
Kotlin提供的用于执行位运算的函数列表:
- shl:带符号左移
- shr:带符号右移
- ushr:无符号右移
- and:按位与
- or:按位或
- xor:按位异或
- inv:按位取反
位运算示例:
println(0x0F and 0xF0)
println(0x0F or 0xF0)
println(0x1 shl 4)
>>>>
0
255
16
7.1.2 重载复合赋值运算符
和二元运算符相似,+=,-=等这些复合赋值运算符也有对应的指定函数,可以被重载。
一般都是对应二元运算符的指定函数再加Assign就是了。如
- +=:plusAssign
- -=:minusAssign
- *=:timesAssign
这里要着重介绍一个问题:这些复合赋值运算符也会调用上节中定义的二元运算符函数。
甚至于,二元运算符函数和复合赋值运算符函数被调用的机会是一样的,而且被要求是唯一的。
例如对于+=,plus和plusAssign都可能被调用。当两者都被定义且适用,编译器会报错。
a += b
//等同于
a = a.plus(b)
//或
a.plusAssign(b)
由此有几点注意:
- val修饰不可变类型的时候,就不能用plusAssign,除非是集合类或者特别定义了函数内容。
- 不可变类一般只提供plus就可以,可变类可以只提供plusAssign。
特别地,Kotlin标准库对于集合的关于运算符的支持:
- +和-:总是返回一个新的集合
- +=和-=:当是可变集合时,始终在一个地方修改它们;当是只读集合时,会返回一个修改过的副本。但在var修饰只读集合后,也是可以使用的。
- 运算数可以是单个元素,也可以是集合。
示例:
//声明:Koltlin标准库为可变集合定义了plusAssign函数
operator fun <T> MutableCollection<T>.plusAssign(element:T){
this.add(element)
}
//调用
val valList = listOf(1,2,3)
var varList = listOf(1,2,3)
val arrayList = arrayListOf(1,2,3)
//valList += 4不允许,会报异常
val newValList = valList + 4
varList += 4
arrayList += 4
println(newValList)
println(varList)
println(arrayList)
>>>>>
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
7.1.3 重载一元运算符
重载一元运算符和上面章节中的方式是相同的,只是对应函数没有参数而已。
可重载的一元运算符对应函数列表:
- +a:unaryPlus
- -a:unaryMinus
- !a:not
- a++,++a:inc
- a–,–a:dec
特殊需要注意的是自增自减运算符,涉及的运算优先级是和基本数据类型用到的一样。
示例:
//声明
operator fun BigDecimal.in

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



