操作符
首先要清楚常见的操作符有哪些?
对一元操作符来说包括'!'、'++'、'--',我们常用的是非操作和自增操作。
我们更熟悉二元操作符,比如
a + b
在这个场景下'+'就是二元操作符,常见的二元操作符就是加减乘除等算术符号。
在Kotlin中还增加了其他二元操作符,比如:in/!in(范围操作符)。
另外还有一些其他的操作符,比如索引访问操作符a[i]、调用操作符a()。
操作符重载
你是否想过类似
println("s" + 1)
这样的代码为何会编译通过,一个String类型和一个Int类型是如何相加的?为什么String类型可以像数组一样可以通过下标访问字符
sss[1]
?
没错,无论'+' 还是取索引都是一种操作符,Kotlin支持操作符的重载,也就是可以将不同类型的对象进行算术运算或其它运算。
我们看看Kotling中String的源码。
public class String : Comparable<String>, CharSequence {
companion object {}
//+操作符重载
public operator fun plus(other: Any?): String
//索引访问操作符重载
public override fun get(index: Int): Char
...
}
复制代码
操作符重载方法需声明
operator
关键字,plus方法对应'+'操作符,参数声明为Any?,可见正式因为String重载了'+'操作符,且参数为Any?,所以在代码中可以用一个String类型的对象"+" 任意一个对象。
接下来看一下操作符对应的重载方法名。
一元操作符 | 对应方法 |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
a++/++a | a.inc() |
a--/--a | a.dec() |
二元操作符 | 对应方法 |
---|---|
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..b | a.rangeTo(b) |
a in b | b.contains(a) |
a !in b | !b.contains(a) |
a > b | a.compareTo(b) > 0 |
回到上面的例子,如果我们稍微调整一下代码
println(1+"s")
这样就会编译报错,可以想见Int类并不支持plus且参数为String的重载。
我们看一下Int类关于plus的重载函数。
# Int
/** Adds the other value to this value. */
public operator fun plus(other: Byte): Int
/** Adds the other value to this value. */
public operator fun plus(other: Short): Int
/** Adds the other value to this value. */
public operator fun plus(other: Int): Int
/** Adds the other value to this value. */
public operator fun plus(other: Long): Long
/** Adds the other value to this value. */
public operator fun plus(other: Float): Float
/** Adds the other value to this value. */
public operator fun plus(other: Double): Double
复制代码
通过重载函数的声明可以确认Int类型只能与一个数字相 '+'。
接下来我们举几个例子加深理解。
class Number constructor(var value: Int)
// 重载一元操作符+,使其对Number中实际数据取绝对值
operator fun Number.unaryPlus(): Number {
this.value = Math.abs(value)
return this
}
// 非运算取相反数
operator fun Number.not(): Number {
this.value = -value
return this
}
// 重载Number类的加法运算符 但并不做真正的加法
operator fun Number.plus(value: Int): Number {
return Number(this.value)
}
// 重载Number类的加法运算符 支持Number类型
operator fun Number.plus(value: Number): Number {
return Number(this.value)
}
// 重载Number类的索引运算 返回某个位上的数字
operator fun Number.get(index: Int): Int {
return this.value / Math.pow(10.toDouble(), index.toDouble()).toInt() % 10
}
复制代码
测试函数
@JvmStatic
fun main(args: Array<String>) {
val number1 = Number(-3)
val number2 = Number(2)
println("Number value = ${number1.value}