操作符重載
一元操作符
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
+a | a.unaryPlus() |
-a | a.unaryMinus() |
!a | a.not() |
++a, a++ | a.inc() |
--a, a-- | a.dec() |
示例:
data class Point(val x: Int, val y: Int)
operator fun Point.unaryMinus() = Point(-x, -y)
operator fun Point.inc() = Point(x + 1, y + 1)
var p = Point(10, 20)
println(-p) // Point(x=10, y=-20)
println(++p) // Point(x=11, y=21)
二元操作符
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
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.mod(b)(棄用) |
a..b | a.rangeTo(b) |
示例:
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)
沒有用于位運算的特殊運算符
- shl — 帶符號左移
- shr — 帶符號右移
- ushr — 無符號右移
- and — 按位與
- or — 按位或
- xor — 按位異或
- inv — 按位取反
示例:
// kotlin
val num = 1 shl 4
println(num) // 16
==>
// java
int num = 1 << 4
in操作符
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
a in b | b.contains(a) |
a !in b | !b.contains(a) |
示例:
data class Rectangle(val upperLeft: Point, val lowerRight: Point)
operator fun Rectangle.contains(p: Point): Boolean {
return p.x in upperLeft.x until lowerRight.x &&
p.y in upperLeft.y until lowerRight.y
}
val rect = Rectangle(Point(10, 20), Point(50, 50))
println(Point(20, 30) in rect) // true
下標(biāo)訪問操作符(通過下標(biāo)來訪問元素:get
和 set
)
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
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, ..., i_n, b) |
示例:
// 一維
operator fun Point.get(index: Int): Int {
return when(index) {
0 -> x
1 -> y
else -> throw IndexOutOfBoundsException("Invalid coordinate $index")
}
}
val p = Point(10, 20)
println(p[1]) // 20
// 二維
data class MutablePoint(var x: Int, var y: Int)
operator fun MutablePoint.set(index: Int, value: Int) {
when(index) {
0 -> x = value
1 -> y = value
else ->
throw IndexOutOfBoundsException("Invalid coordinate $index")
}
}
val p = MutablePoint(10, 20)
p[1] = 42
println(p) // MutablePoint(x=10, y=42)
調(diào)用操作符(invoke)
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
a() | a.invoke() |
a(i) | a.invoke(i) |
a(i, j) | a.invoke(i, j) |
a(i_i, …, i_n) | a.invoke(i_1, …, i_n) |
圓括號轉(zhuǎn)換為調(diào)用帶有適當(dāng)數(shù)量參數(shù)的 invoke
示例:
class Greeter(val greeting: String) {
operator fun invoke(name: String) {
println("$greeting, $name!")
}
}
val bavarianGreeter = Greeter("Servus")
bavarianGreeter("Dmitry") // Servus, Dmitry!
==>
val bavarianGreeter = Greeter("Servus")("Dmitry") // Servus, Dmitry!
可以通過重寫invoke
實例工廠模式
object Any {
operator fun invoke(name: String): String {
return name
}
operator fun invoke(number: Int): Int {
return number
}
}
val string = Any("Hello World!");
val int = Any("1");
println("$string, $int") // Hello World! 1
復(fù)合賦值運算符
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
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.modAssign(b) (棄用) |
示例:
operator fun <T> MutableCollection<T>.plusAssign(element: T) {
this.add(element)
}
val list = arrayListOf(1, 2)
list += 3
val newList = list + listOf(4, 5)
println(list) // [1, 2, 3]
println(newList) // [1, 2, 3, 4, 5]
比較運算符(equals)
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
a == b | a?.equals(b) ?: (b === null) |
a != b | !(a?.equals(b)) ?: (b ===null) |
(等式校驗 ==
被轉(zhuǎn)換為equals
函數(shù)的調(diào)用宜雀,以及null
的校驗)
注意:===
和 !==
(同一性檢查)不可重載制跟,因此不存在對他們的約定撩嚼。
這個 ==
操作符有些特殊:它被翻譯成一個復(fù)雜的表達(dá)式被丧,用于篩選 null
值齿诞。 null == null
總是 true指蚜,對于非空的 x
麻裳,x == null
總是 false 而不會調(diào)用 x.equals()
口蝠。
示例:
class Point(val x: Int, val y: Int) {
override fun equals(obj: Any?): Boolean {
if (obj === this) return true
if (obj !is Point) return false
return obj.x == x && obj.y == y
}
}
println(Point(10, 20) == Point(10, 20)) // true
println(Point(10, 20) != Point(5, 5)) // true
println(null == Point(1, 2)) // false
表達(dá)式 | 函數(shù)名 |
---|---|
+a | unaryPlus |
-a | unaryMinus |
!a | not |
++a, a++ | inc |
—a, a-- | dec |
示例:
operator fun Point.unaryMinus(): Point {
return Point(-x, -y)
}
val p = Point(10, 20)
println(-p) // Point(x=10, y=-20)
比較操作符(compareTo)
表達(dá)式 | 對應(yīng)函數(shù) |
---|---|
a > b | a.compareTo(b) > 0 |
a < b | a.compareTo(b) < 0 |
a >= b | a.compareTo(b) >= 0 |
a <= b | a.compareTo(b) <= 0 |
所有的比較都轉(zhuǎn)換為對 compareTo
的調(diào)用,這個函數(shù)需要返回 Int
值
示例:
class Person(val firstName: String, val lastName: String): Comparable<Person> {
override fun compareTo(other: Person): Int {
return compareValuesBy(this, other, Person::lastName, Person::firstName)
}
}
val p1 = Person("Alice", "Smith")
val p2 = Person("Bob", "Johnson")
println(p1 < p2) // false
參考資料: