运算符重载
- 运算符重载
- 转换
- 一元运算符
- 二元操作符
- 函数命名的中缀调用
- 转换
运算符重载
Kotlin允许我们事先一些我们自定义类型的运算符实现,这些运算符有固定的表示和固定的优先级。为实现这样的运算符,饿哦们提供了固定名字的数字函数和扩展函数。比如二元运算符的左值和一元运算符的参数类型
转换
一元运算符
表达式 | 转换 |
---|---|
+a | a.pluns() |
-a | a.minus() |
!a | a.not() |
决定a的类型,假设为T
寻找接受者是T的无参函数
plus()
,比如数字函数或者扩展函数如果这样的函数缺失或不明确,则返回错误
如果函数是当前函数或返回类型是
R
则表达式+a
是R
类型
注意这些操作符合其他的一样,都是被优化为基本类型并且不会产生多余的开销
表达式 | 转换 |
---|---|
a++ | a.inc()+see below |
b– | b.dex()+see below |
这些操作符允许修改接收者和返回类型
编译器是这样解决有后缀的操作符的,如a++
:
决定a的类型,假设T寻找无参函数
inc()
,作用在接收者T如果返回类型是R必须是T的子类
计算表达式的效果是:
把a的初始值存储在a()中
把a.inc()的结果作用在a上
把a()作为表达式的返回值
a—、++a、—a 的步骤是一样的
二元操作符
表达式 | 转换 |
---|---|
a+b | a.plus(b) |
a-b | a.minus(b) |
a*b | a.times(b) |
a/b | a.div(b) |
a%b | a.mod(b) |
a…b | a.rangeTo(b) |
表达式只是解决了该表中翻译为列的表达式
表达式 | 转换 |
---|---|
a in b | b.contains(a) |
a !in b | !b.contains(a) |
in和!in的产生步骤是一样的,但是参数顺序是相反的
标志 | 转换 |
---|---|
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,…,o_n,b) |
方括号被准换为get set函数
标志 | 转换 |
---|---|
a(i) | a.invoke(i) |
a(i,j) | a.invoke(i,j) |
a(i_1,…,i_n) | A.invoke(i_1,…,i_n) |
括号被准换为带有正确参数的invoke参数
表达式 | 转换 |
---|---|
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时编译器是下面这样实现的:
右边列的函数是否可用
对应的二元函数是否也可用,不可用报告错误
确定它的返回值是
Unit
是否报告错误生成
a.plusAssign(b)
否则试着生成a=a+b代码
表达式 | 转换 |
---|---|
a==b | a?.equals(b) ?: b.identityEquals(null) |
a!=b | !(a?.equals(b) ?: b.identityEquals(null)) |
注意=== 和!==是不允许重载的
==操作符有两点特别:
它被翻译成一个复杂的表达式,用于筛选空值,而且null==null是真
它需要带有特定签名的函数,而不仅仅是特定名称的函数,下面这样:
fun equals(other:Any?):Boolean
或者用相同的参数列表和返回类型的扩展功能
标志 | 转换 |
---|---|
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
值
命名函数的中缀调用
函数用infix
关键字标识的函数,叫中缀函数。
中缀函数必须符合以下几点:
必须是成员函数或者是扩展函数
必须只有一个参数
这个参数必须是可变参数类型,而且不能有默认值
必须使用infix关键字修饰
//中缀函数
infix fun String.add(str:String):String{
return this+str
}
fun testInfix(){
val xing="wang"
val ming="yong"
println("my name is ${xing add ming}")
}
输出
my name is wangyong