学而不思则罔,思而不学则殆
运算符重载是Kotlin提供的一个比较有趣的语法糖。我们知道。Java中 有许多语言内置的运算符关键字,如= - * / % ++ --.而Kotlin中可以将所有的运算符甚至其他的关键字进行重载,扩展这些运算符和关键字的用法
每个人从小就学了四则运算,在编程语言中,两个数字相加表示求和,两个字符串相加,表示对这两个字符进行拼接。但是在Kotlin中,运算符却允许我们对任意两个对象进行相加或者进行更多其他的运算操作。
加法运算符
传统加法运算符
val sum = 1 + 2
println("sum=$sum")//sum=3
val name = "Zhang" + "Yu"
println("name=$name")//name=ZhangYu
重载运算符
格式如下:
class Test {
operator fun plus(test: Test): Test {
// FIXME: 2020/11/4 处理相加逻辑
return this + test
}
}
结构中,关键字operator 和函数名plus是不变的,而接受的参数和返回的值可以根据业务自己设置。
调用方法如下:
fun main() {
val test1 = Test()
val test2 = Test()
val test3 = test1 + test2
val test4 = test1.plus(test2)
}
test1 + test2看上去很神奇,这只是一种语法糖,他会在编译的时候被转换成test1.plus(test2)。
现在我们实现一个Money相加的逻辑:
class Money(val value: Int) {
operator fun plus(money: Money): Money {
// FIXME: 2020/11/4 处理相加逻辑
val sum = value + money.value;
return Money(sum)
}
}
调用demo:
fun main() {
val money1 = Money(10)
val money2 = Money(10)
val money = money1 + money2
println(money.value)//20
}
这样是不是不够方便,我们也可以直接接收一个整型:
class Money(val value: Int) {
operator fun plus(money: Money): Money {
// FIXME: 2020/11/4 处理相加逻辑
val sum = value + money.value;
return Money(sum)
}
operator fun plus(qian: Int): Money {
// FIXME: 2020/11/4 处理相加逻辑
val sum = value + qian;
return Money(sum)
}
}
fun main() {
val money1 = Money(10)
val money2 = Money(10)
val money3 = money1 + money2
val money4 = money1 + 30
println(money3.value)//20
println(money4.value)//40
}
查看一下Kotlin字节码可以发现,实际上调用的plus方法。
当然你还可以加上其他相加逻辑,比如给Money加上单位,人民币和美元之间怎么转换等等。
前面我们花时间了解了plus运算符的重载,实际上Kotlin中还有很多:
语法运算符与实际调用函数对比
语法糖表达式 | 实际调用函数 |
---|---|
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) |
a++ | a.inc() |
a– | a.dec() |
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
a == b | a.equals() |
a > b | a.compareTo(b) |
a < b | a.compareTo(b) |
a >=b | a.compareTo(b) |
a <=b | a.compareTo(b) |
a…b | a.rangTo(b) |
a[b] | a.get(b) |
a[b] = c | a.set(b,c) |
a in b | b.contains(a) |
语法糖测试
minus
times
字符串times
operator fun String.times(n: Int): String {
val builder = StringBuilder()
kotlin.repeat(n, {
builder.append(this)
})
return builder.toString()
}
operator fun String.times(n: Int): String {
val builder = StringBuilder()
kotlin.repeat(n) {
builder.append(this)
}
return builder.toString()
}
fun main() {
println("zhangyu".times(3))
}
zhangyuzhangyuzhangyu