天天看點

Kotlin-運算符重載

前言

Kotlin 允許我們為自己的類型提供預定義的一組操作符的實作。這些操作符具有固定的符号表示 (如 + 或 *)和固定的優先級。為實作這樣的操作符,我們為相應的類型(即二進制操作符左側的類型和一進制操作符的參數類型)提供了一個固定名字的成員函數或擴充函數。 重載操作符的函數需要用 operator 修飾符标記。

操作符介紹

  • 一進制字首操作符

    表達式 +a -> 翻譯為 a.unaryPlus()

    表達式 -a -> 翻譯為 a.unaryMinus()

    表達式 !a -> 翻譯為 a.not()

  • 執行的步驟

    1 确定a的類型

    2 為接收者 T 查找一個帶有 operator 修飾符的無參函數 unaryPlus()

    3 如果函數不存在或不明确,則導緻編譯錯誤;

    4 如果函數存在且其傳回類型為 R,那就表達式 +a 具有類型 R;

  • 使用執行個體
/**
 *  表達式  +a  -> 翻譯為   a.unaryPlus()
 *  表達式  -a  -> 翻譯為   a.unaryMinus()
 *  表達式  !a  -> 翻譯為   a.not()
 */
data class Point(val x: Int, val y: Int)

// 負号一進制字首符
operator fun Point.unaryMinus() = Point(-x, -y)

// 正号一進制字首符
operator fun Point.unaryPlus() = Point(+x, +y)

// !一進制字首運算符
operator fun Point.not() = Point(x,y)


fun main() {
    val p1 = Point(12, 24)
    println(-p1)
    println(!p1)
}
           
  • 遞增和遞減

    表達式 a++ -> 翻譯為 a.inc()

    表達式 a-- -> 翻譯為 a.dec()

  • 執行的步驟

    編譯器執行以下步驟來解析字尾形式的操作符,例如 a++:

    确定 a 的類型,令其為 T;

    查找一個适用于類型為 T 的接收者的、帶有 operator 修飾符的無參數函數 inc();

    檢測函數的傳回類型是 T 的子類型。

    計算表達式的步驟是:

    把 a 的初始值存儲到臨時存儲 a0 中;

    把 a.inc() 結果指派給 a;

    把 a0 作為表達式的結果傳回。

    對于 a–,步驟是完全類似的。

    對于字首形式 ++a 和 --a 以相同方式解析,其步驟是:

    把 a.inc() 結果指派給 a;

    把 a 的新值作為表達式結果傳回。

  • 使用執行個體
/***
 * 遞增運算符 ++point 會把新的結果傳回
 * 遞增運算符 point++ 會把新的結果存儲在一個變量中

 */
operator fun Point.inc() = Point(x + 1, y + 1)

/**
 * 遞減運算符 --point 會把新的結果傳回
 * 遞增運算符 point++ 會把新的結果存儲在一個變量中

 */
operator fun Point.dec() = Point(x - 1, y - 1)
fun main() {
    var p1 = Point(12, 24)
    p1 = ++p1
    var p2 = p1++
    println(p1)
    println(p2)

}


           
  • 二進制操作符
表達式 翻譯為
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.rangTo(b)
  • 使用執行個體
/***
 * 重載 + 這個運算符
 */
operator fun String.plus(s:String) = this+s

/***
 *  重載 — 這個運算符
 */
operator fun String.minus(s:String) = this+ "減号運算符的重載"+s

fun main() {
    var s = "栾小黑"
    var ss = s+" hello world"
    var sss  = s-"helloworld"
    println(ss)
    println(sss)
}

           

對應的運算符對應的方法可以在官網上看到,運算符的重載最重要的是一個關鍵在 operator的使用

繼續閱讀