Kotlin研發第二十彈——運算符重載

運算符重載

  • 運算符重載
    • 轉換
      • 一元運算符
      • 二元操作符
    • 函數命名的中綴調用

運算符重載

Kotlin允許我們事先一些我們自定義類型的運算符實現,這些運算符有固定的表示和固定的優先級。爲實現這樣的運算符,餓哦們提供了固定名字的數字函數和擴展函數。比如二元運算符的左值和一元運算符的參數類型

轉換

一元運算符

表達式 轉換
+a a.pluns()
-a a.minus()
!a a.not()

決定a的類型,假設爲T

尋找接受者是T的無參函數plus(),比如數字函數或者擴展函數

如果這樣的函數缺失或不明確,則返回錯誤

如果函數是當前函數或返回類型是R則表達式+aR類型

注意這些操作符合其他的一樣,都是被優化爲基本類型並且不會產生多餘的開銷

表達式 轉換
a++ a.inc()+see below
b– b.dex()+see below

這些操作符允許修改接收者和返回類型

編譯器是這樣解決有後綴的操作符的,如a++:

決定a的類型,假設T尋找無參函數inc(),作用在接收者T

如果返回類型是R必須是T的子類

計算表達式的效果是:

把a的初始值存儲在a()中

把a.inc()的結果作用在a上

把a()作爲表達式的返回值

a—、++a、—a 的步驟是一樣的

二元操作符

表達式 轉換
a+b a.plus(b)
a-b a.minus(b)
a*b a.times(b)
a/b a.div(b)
a%b a.mod(b)
a…b a.rangeTo(b)

表達式只是解決了該表中翻譯爲列的表達式

表達式 轉換
a in b b.contains(a)
a !in b !b.contains(a)

in和!in的產生步驟是一樣的,但是參數順序是相反的

標誌 轉換
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,…,o_n,b)

方括號被準換爲get set函數

標誌 轉換
a(i) a.invoke(i)
a(i,j) a.invoke(i,j)
a(i_1,…,i_n) A.invoke(i_1,…,i_n)

括號被準換爲帶有正確參數的invoke參數

表達式 轉換
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)

在分配a+=b時編譯器是下面這樣實現的:

右邊列的函數是否可用

對應的二元函數是否也可用,不可用報告錯誤

確定它的返回值是Unit是否報告錯誤

生成a.plusAssign(b)

否則試着生成a=a+b代碼

表達式 轉換
a==b a?.equals(b) ?: b.identityEquals(null)
a!=b !(a?.equals(b) ?: b.identityEquals(null))

注意=== 和!==是不允許重載的

==操作符有兩點特別:
它被翻譯成一個複雜的表達式,用於篩選空值,而且null==null是真

它需要帶有特定簽名的函數,而不僅僅是特定名稱的函數,下面這樣:

fun equals(other:Any?):Boolean

或者用相同的參數列表和返回類型的擴展功能

標誌 轉換
a>b a.compareTo(b)>0
a<b a.compareTo(b)<0
a>=b a.compareTo(b)>=0
a<=b a.compareTo(b)<=0

所有的比較都轉爲compareTo的調用,這個函數需要返回Int

命名函數的中綴調用

函數用infix關鍵字標識的函數,叫中綴函數。

中綴函數必須符合以下幾點:

必須是成員函數或者是擴展函數

必須只有一個參數

這個參數必須是可變參數類型,而且不能有默認值

必須使用infix關鍵字修飾

//中綴函數
infix fun String.add(str:String):String{
    return this+str
}

fun testInfix(){
    val xing="wang"
    val ming="yong"
    println("my name is ${xing add ming}")
}

輸出

my name is wangyong
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章