《Kotlin实战》-第07章:运算符重载及其他约定

第七章 运算符重载及其他约定

约定的定义比较模糊,一般说是通过调用自己代码中定义的函数,来实现特定语言结构。
在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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值