Kotlin 允許我們?yōu)樽约旱念愋吞峁╊A(yù)定義的一組操作符的實(shí)現(xiàn)。這些操作符具有固定的符號(hào)表示
(如 + 或 *)和固定的優(yōu)先級(jí)。為實(shí)現(xiàn)這樣的操作符,我們?yōu)橄鄳?yīng)的類型(即二元操作符左側(cè)的類型和一元操作符的參數(shù)類型)提供了一個(gè)固定名字的成員函數(shù)
或擴(kuò)展函數(shù)。
重載操作符的函數(shù)需要用 operator 修飾符標(biāo)記。
在這里我們描述為不同操作符規(guī)范操作符重載的約定。
| 表達(dá)式 | 翻譯為 |
|---|---|
+a |
a.unaryPlus() |
-a |
a.unaryMinus() |
!a |
a.not() |
這個(gè)表是說(shuō),當(dāng)編譯器處理例如表達(dá)式 +a 時(shí),它執(zhí)行以下步驟:
a 的類型,令其為 T。T 查找一個(gè)帶有 operator 修飾符的無(wú)參函數(shù) unaryPlus(),即成員函數(shù)或擴(kuò)展函數(shù)。R,那就表達(dá)式 +a 具有類型 R。注意 這些操作以及所有其他操作都針對(duì)基本類型做了優(yōu)化,不會(huì)為它們引入函數(shù)調(diào)用的開銷。
| 表達(dá)式 | 翻譯為 |
|---|---|
a++ |
a.inc() + 見下文 |
a-- |
a.dec() + 見下文 |
inc() 和 dec() 函數(shù)必須返回一個(gè)值,它用于賦值給使用++ 或 -- 操作的變量。它們不應(yīng)該改變?cè)谄渖险{(diào)用 inc() 或 dec() 的對(duì)象。
編譯器執(zhí)行以下步驟來(lái)解析后綴形式的操作符,例如 a++:
a 的類型,令其為 T。T 的接收者的、帶有 operator 修飾符的無(wú)參數(shù)函數(shù) inc()。T 的子類型。計(jì)算表達(dá)式的步驟是:
a 的初始值存儲(chǔ)到臨時(shí)存儲(chǔ) a0 中,a.inc() 結(jié)果賦值給 a,a0 作為表達(dá)式的結(jié)果返回。對(duì)于 a--,步驟是完全類似的。
對(duì)于前綴形式 ++a 和 --a 以相同方式解析,其步驟是:
a.inc() 結(jié)果賦值給 a,a 的新值作為表達(dá)式結(jié)果返回。| 表達(dá)式 | 翻譯為 |
|---|---|
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) |
對(duì)于此表中的操作,編譯器只是解析成翻譯為列中的表達(dá)式。
請(qǐng)注意,自 Kotlin 1.1 起支持 rem 運(yùn)算符。Kotlin 1.0 使用 mod 運(yùn)算符,它在
Kotlin 1.1 中被棄用。
| 表達(dá)式 | 翻譯為 |
|---|---|
a in b |
b.contains(a) |
a !in b |
!b.contains(a) |
對(duì)于 in 和 !in,過(guò)程是相同的,但是參數(shù)的順序是相反的。
{:#in}
| 表達(dá)式 | 翻譯為 |
|---|---|
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) |
方括號(hào)轉(zhuǎn)換為調(diào)用帶有適當(dāng)數(shù)量參數(shù)的 get 和 set。
| 表達(dá)式 | 翻譯為 |
|---|---|
a() |
a.invoke() |
a(i) |
a.invoke(i) |
a(i, j) |
a.invoke(i, j) |
a(i_1, ……, i_n) |
a.invoke(i_1, ……, i_n) |
圓括號(hào)轉(zhuǎn)換為調(diào)用帶有適當(dāng)數(shù)量參數(shù)的 invoke。
| 表達(dá)式 | 翻譯為 |
|---|---|
a += b |
a.plusAssign(b) |
a -= b |
a.minusAssign(b) |
a *= b |
a.timesAssign(b) |
a /= b |
a.divAssign(b) |
a %= b |
a.modAssign(b) |
{:#assignments}
對(duì)于賦值操作,例如 a += b,編譯器執(zhí)行以下步驟:
plusAssign() 對(duì)應(yīng)于 plus())也可用,那么報(bào)告錯(cuò)誤(模糊)。Unit,否則報(bào)告錯(cuò)誤。a.plusAssign(b) 的代碼a = a + b 的代碼(這里包含類型檢查:a + b 的類型必須是 a 的子類型)。注意:賦值在 Kotlin 中不是表達(dá)式。
{:#Equals}
| 表達(dá)式 | 翻譯為 |
|---|---|
a == b |
a?.equals(b) ?: (b === null) |
a != b |
!(a?.equals(b) ?: (b === null)) |
注意:=== 和 !==(同一性檢查)不可重載,因此不存在對(duì)他們的約定
這個(gè) == 操作符有些特殊:它被翻譯成一個(gè)復(fù)雜的表達(dá)式,用于篩選 null 值。null == null 總是 true,對(duì)于非空的 x,x == null 總是 false 而不會(huì)調(diào)用 x.equals()。
| 表達(dá)式 | 翻譯為 |
|---|---|
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)換為對(duì) compareTo 的調(diào)用,這個(gè)函數(shù)需要返回 Int 值
我們可以通過(guò)中綴函數(shù)的調(diào)用 來(lái)模擬自定義中綴操作符。