运算符和表达式
Kotlin基本支持Java的全部运算符(可能有些种子语法上存在差异),Kotlin不支持三目运算符。
1. 与Java相同的运算符
Kotlin的运算符都是以方法形式实现的,这些运算符都具有特定的符号和固定的优先级。
-
单目前缀运算符
运算符 对应的方法 +a a.unaryPlus() -a a.unaryMinus() !a a.not fun main(args: Array<String>) { val a = 20 val b = -a val c = a.unaryMinus() println("b: $b, c: $c") // b: -20, c: -20 val flag = true val f1 = !flag val f2 = flag.not() println("f1: $f1, f2: $f2") // f1: false, f2: false }
如果在API中发现某个类有
unaryPlus()
、unaryMinus()
、not()
方法,那就说明可对该类的实例使用单目前缀运算符+
、-
、!
进行运算。 -
自加和自减运算符
运算符 对应的方法 a++ a.inc() a-- a.dec() 如果在API中发现某个类有
inc()
、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) 如果在API中发现某个类有一个带参数的
plus()
、minus()
、times()
、div()
、rem()
、rangeTo()
方法,那就说明可对该类的实例使用以上双目算术运算符。 -
in和!in运算符
运算符 对应的方法 a in b b.contains(a) a !in b !b.contains(a) fun main(args: Array<String>) { val str = "JamFF" println(str.contains("java")) println("java" in str) val arr = arrayOf(8, 32, 94, 53, 10) println(arr.contains(53)) println(53 in arr) }
如果在API中发现某个类有一个带参数
contains()
方法,那就说明可对该类的实例使用in
、!in
运算符。 -
索引访问运算符
运算符 对应的方法 a[i] a.get(i) a[i, j] a.get(i, j) a[i_l, ..., i_n] a.get(i_l, ..., i_n) a[i]=b a.set(i ,b) a[i, j]=b a.set(i, j, b) a[i_l,...,i_n]=b a.set(i_l ,..., i_n) -
调用运算符
运算符 对应的方法 a() a.invoke() a(b) a.invoke(b) a(b1, b2) a.invoke(b1, b2) a(b1, b2, b3, ...) a.invoke(b1, b2, b3, ...) fun main(args: Array<String>) { val s = "java.lang.String" val mtd = Class.forName(s).getMethod("length") // 使用传统方法,使用Method对象的invoke方法 println(mtd.invoke("java")) // 输出4 // 使用调用运算符 println(mtd("java")) // 输出4 }
-
广义赋值运算符
运算符 对应的方法 a += b a.plusAssign(b) a -= b a.minusAssign(b) a *= b a.timesAssign(b) a /= b a.divAssign(b) a %= b a.remAssign(b) -
相等于不等运算符
运算符 对应的方法 a == b a?.equals(b):(b===null) a != b !(a?.equals(b)?:(b===null)) Kotlin中
==
和equals
本质是一样的,只不过==
避免了空指针;而Java中比较对象的==
和!=
在Kotlin中由===
和!==
代替。 -
比较运算符
运算符 对应的方法 a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a >= b a.compareTo(b) >= 0 a <= b a.compareTo(b) <= 0 如果在API中发现某个类实现了
Comparable
方法,那就该类的实例即可使用比较运算符来比较大小。
2. 位运算符
Kotlin支持的位运算符同样有7个,但是并不是特殊字符形式,而是以infix
函数的形式给出的,因此只能用函数名执行这些位运算符。
-
and(bits)
:按位与。 -
or(bits)
:按位或。 -
inv(bits)
:按位非。 -
xor(bits)
:按位异或。 -
shl(bits)
:左移运算符。 -
shr(bits)
:右移运算符。 -
ushr(bits)
:无符号右移运算符。
Kotlin的位运算符只能对Int
和Long
两种数据类型起作用。
3. 区间运算符
-
闭区间运算符
a..b
定义一个从a到b(包含a和b)的所有值的区间。fun main(args: Array<String>) { val range = 2..6 for (num in range) { print("$num ") // 输出2 3 4 5 6 } }
-
半开区间运算符
a until b
定义一个从a到b(包含a,不包含b)的所有值的区间。
利用半开区间便利数组的列表时非常方便。fun main(args: Array<String>) { val books = arrayOf("Swift", "Kotlin", "C", "C++") for (index in 0 until books.size) { println("第${index + 1}中语言是:${books[index]}") } }
-
反向区间
如果希望区间从大到小,可以使用downTo
运算符(其实是一个infix
函数),该运算符同样是一个闭区间。fun main(args: Array<String>) { val range = 6 downTo 2 for (num in range) { print("$num ") // 输出6 5 4 3 2 } }
-
区间步长
前面区间的默认步长都是1,可通过step
运算符(其实是一个infix
函数)指定区间步长。fun main(args: Array<String>) { for (num in 7 downTo 1 step 2) { print("$num ") // 输出7 5 3 1 } }
4. 运算符重载
重载运算符的方法需要运用operator
修饰符进行标记。
-
重载单目前缀运算符
data class Data(val x: Int, val y: Int) { // 为Data类定义一个unaryMinus()方法 operator fun unaryMinus(): Data { return Data(-x, -y) } } // 以扩展方法的形式为Data类定义unaryPlus()方法 operator fun Data.unaryPlus(): Data { return Data(-x, -y) } fun main(args: Array<String>) { val d = Data(4, 10) println(-d) println(+d) }
-
重载自加和自减运算符
data class Data(val x: Int, val y: Int) { // 为Data类定义一个inc()方法 operator fun inc(): Data { return Data(x + 1, y + 1) } } // 以扩展方法的形式为Data类定义dec()方法 operator fun Data.dec(): Data { return Data(x - 1, y - 1) } fun main(args: Array<String>) { var d = Data(4, 10) println(d++) // 输出Data(x=4, y=10) println(d) // 输出Data(x=5, y=11) var dd = Data(9, 20) println(--dd) // 输出Data(x=8, y=19) println(dd) // 输出Data(x=8, y=19) }
-
重载双目算术运算符
data class Point(val x: Int, val y: Int) { // 为Point类定义一个minus()方法 operator fun minus(target: Point): Double { return Math.hypot((this.x - target.x).toDouble() , (this.y - target.y).toDouble()) } } // 以扩展方法的形式为Point类定义dec()方法 operator fun Point.times(target: Point): Int { return Math.abs(this.x - target.x) * Math.abs(this.y - target.y) } fun main(args: Array<String>) { val p1 = Point(0, 0) val p2 = Point(3, 4) println("p1与p2的距离为:${p1 - p2}") // 输出5 println("p1与p2围成的矩形面积为:${p1 * p2}") // 输出12 }
重点
-
in
和!in
运算符 -
==
和===
运算符 - 位运算符
- 区间运算符
- 运算符重载