Kotlin——初級篇(五):操做符與操做符重載一

本篇文章爲你們詳細的介紹Koltin特有的操做符重載。或許對於有編程經驗的朋友來講,操做符這個詞絕對不陌生,就算沒有任何編輯基礎的朋友,數學中的算數運算符也毫不陌生。例如(+、-、*、/、>、<、>=、<=)等。而算數運算符是編程語言中的一種操做符而已。就算你沒有任何基礎,也請你詳細的看完這篇文章,我相信你會頗有收穫的。html

目錄

1、約定

所謂預約:即指Kotlin容許咱們爲本身的類型提供預約義的一組操做符的實現。這些操做符具備固定的符號表示(如 +*)和固定的優先級。爲實現這樣的操做符,咱們爲相應的操做類型提供了一個固定名字的函數。這樣的技術,稱爲約定git

由於由類實現的接口集是固定的,而Kotlin不能爲了實現其餘接口而修改現有的類,所以通常經過擴展函數的機制來實現爲現有的類增添新的約定方法,從而適應任何現有的Java類。github

2、操做符與操做符重載

根據操做數據個數的不一樣,分爲兩種操做類型:編程

  1. 一元操做:即指操做數只有一個的狀況
  2. 二元操做:即指操做數存在二兩或多個的狀況。特別說明:在存在多個操做數的狀況下,會用複合運算或拆分爲多個運算。

2.一、一元操做

一元操做:即指一個操做數的狀況,數組

2.1.一、簡單的一元操做運算

這裏分爲三種狀況有三種一元操做:yii

  • + 表示爲操做數實現一個正號的意思,其操做數爲數值型
  • - 表示爲操做數實現一個負號的意思,其操做數爲數值型
  • ! 表示取反的意思,其操做數爲boolean類型

提供一個表格直觀的展現:編程語言

操做符 重載
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()

例:函數

var a = 1
var b = -2
var c = true
var d = false

// 操做符實現
println("+a = ${+a}\t -a = ${-a}\t !c = ${!c}")
println("+b = ${+b}\t -b = ${-b}\t !d = ${!d}")

// 操做符重載實現
println("+a = ${a.unaryPlus()}\t -a = ${a.unaryMinus()}\t !c = ${c.not()}")
println("+b = ${b.unaryPlus()}\t -b = ${b.unaryMinus()}\t !d = ${d.not()}")

輸出結果爲:spa

+a = 1	 -a = -1	 !c = false
+b = -2	 -b = 2	 !d = true
+a = 1	 -a = -1	 !c = false
+b = -2	 -b = 2	 !d = true
2.1.二、複雜的一元操做

複雜的一元操做符即指,對操做數進行自增、自減操做。和Java是同樣的翻譯

這裏主要有4種狀況:

  • 後綴自增:表示爲操做數進行自增操做,其操做數爲數值型。例如:a++
  • 後綴自減:表示爲操做數進行自減操做,其操做數爲數值型。例如:a--
  • 前綴自增:表示爲操做數進行自增操做,其操做數爲數值型。例如:++a
  • 前綴自減:表示爲操做數進行自增操做,其操做數爲數值型。例如:--a

提供一個表格直觀的展現:

操做符 重載 表示
a++ a.inc() a = a.also{ a.inc() }
a-- a.dec() a = a.also{ a.dec() }
++a a.inc() a = a.inc().also{ a = it }
--a a.dec() a = a.dec().also{ a = it }

解釋:操做符++的重載爲inc(),操做符--的重載爲dec()。可是前綴操做和後綴操做是有着明顯的區別的:

  • 後綴操做是第一次調用的時候不執行自身。在第二次開始進行自增或自減操做。
  • 前綴操做是第一次調用的時候就執行自增或自減操做

實例:

var a = 10
var b = 10
var c = 10
var d = 10

// 操做符實現
println("a++ = ${a++} \t b-- = ${b--} \t ++c = ${++c} \t --d = ${--d}")

// 操做符重載方式實現,或許你看不明白上表中代碼,不過這不要緊,你只要記住上面前綴與後綴操做的區別就行
a.also { a.inc() }
b.also { b.dec() }
c.inc().also { c = it }
d.dec().also { d = it }
println("a = $a \t b = $b \t c = $c \t d = $d")

輸出結果爲:

a++ = 10 	 b-- = 10 	 ++c = 11 	 --d = 9
a = 10 	 b = 10 	 c = 11 	 d = 9

2.2 二元操做

二元操做:即指操做數存在二兩或多個的狀況。

2.2.一、簡單的二元操做

簡單的二元操做有:

  • a + b,表示兩個操做數相加,值得注意的是若某一個操做數爲String類型時。其返回值爲String類型,當且僅當兩個操做數都爲數值型時,其返回值纔會數值型。
  • a - b,表示兩個操做數相減,返回值爲數值型
  • a * b,表示兩個操做數相乘,返回值爲數值型
  • a / b,表示兩個操做數相除,返回值爲數值型
  • a % b,表示兩個操做數相除後的餘數,官方稱之爲,即a模以b 。返回值爲Int
  • a .. b,表示範圍(區間),這裏不詳細說明,在下面一點的區間操做符一塊兒講解。

這裏提供一個表格直觀的展現:

操做符 重載
a + b a.plus(b)
a - b a.minus(b)
a * b a.tiems(b)
a / b a.div(b)
a % b a.rem(b) 或 a.mod(b)
a .. b a.rangTo(b)

這裏值得注意的是:a % b的重載爲a.rem()a.mod()。不過a.mod()Koltin1.0版本的重載方法,如今已經棄用了,Koltin1.1以及以上版本使用a.rem()重載方法

// 簡單的二元操做
val a = 10
val b = 2
val c = "2"
val d = "Kotlin"

// 操做符實現
println("a + d = " + a + d)
println("c + d = " + c + d)
println("a + b = ${a + b} \t a - b = ${a - b} \t a * b = ${a * b} \t a / b = ${a / b} \t a % b = ${a % b}")

// 操做符重載實現
// println("a + d = ${a + d}") 錯誤:字符串模板限制只能爲數值型
println("a + b = ${a.plus(b)} \t a - b = ${a.minus(b)} \t a * b = ${a.times(b)} \t a / b = ${a.div(b)} \t a % b = ${a.rem(b)}")
// println(a.plus(d))  錯誤:由於第一個操做數`a`限制了其plus()方法的參數,
// println(d.plus(a))  正確:由於plus()方法的參數爲超(Any)類型

輸出結果爲:

a + d = 10Kotlin
c + d = 2Kotlin
a + b = 12 	 a - b = 8 	 a * b = 20 	 a / b = 5 	 a % b = 0
a + b = 12 	 a - b = 8 	 a * b = 20 	 a / b = 5 	 a % b = 0

2.2.二、複合二元操做

複合的二元操做有:

  • a += b,表示第一個操做數的的值爲第一個操做數加上第二個操做數,值得注意的是若某一個操做數爲String類型時。其返回值爲String類型,當且僅當兩個操做數都爲數值型時,其返回值纔會數值型。
  • a -= b,表示第一個操做數的的值爲第一個操做數減去第二個操做數,返回值爲數值型
  • a *= b,表示第一個操做數的的值爲第一個操做數乘以第二個操做數,返回值爲數值型
  • a /= b,表示第一個操做數的的值爲第一個操做數除以第二個操做數,返回值爲數值型
  • a %= b,表示第一個操做數的的值爲第一個操做數模以第二個操做數 。返回值爲Int

這裏提供一個表格直觀的展現:

操做符 表示 重載
a += b a = a + b a = a.plus(b)
a -= b a = a - b a = a.minus(b)
a *= b a = a * b a = a.tiems(b)
a /= b a = a / b a = a.div(b)
a %= b a = a % b a = a.rem(b)

例: 操做符實現

var b = 2
var a = 10
var c = "Kotlin"

// 主要演示字符串的+=
c += a                          等價於  c = c.plus(a)
print("c = $c \t")

a += b                          等價於  a = a.plus(b)
print("a = $a \t")

a = 10
a -= b                          等價於  a = a.minus(b)
print("a = $a \t")

a = 10
a *= b                          等價於  a = a.tiems(b)
print("a = $a \t")

a = 10
a /= b                          等價於  a = a.div(b)
print("a = $a \t")

a = 10
a % b                          等價於  a = a.rem(b)
print("a = $a \t")

輸出結果爲:

c = Kotlin10 	a = 12 	a = 8 	a = 20 	a = 5 	a = 0

或許你會說這裏爲何沒有Kotlin的版本呢?你在看官方文檔或者其餘人一些博客文章的時候可能有這樣a += b <=> a.plusAssign()的操做。可是我告訴你a.plusAssign()不是這樣用的,你能夠看源碼知道primitives.kt文件中肯本就不存在plusAssign()這個方法。由於Koltin賦值不是表達式。即 a += b <=> a = a + bKotlin中是a = a.plus(b)。不過數組與集合是同時存在plus()plusAssign()這兩個函數的。

還有一點就是:若是個人第一個操做數定義爲val(不可變)類型時,a += b這個表達式會編譯出錯。

上面說到了在源碼primitievs.kt文件中不存在plusAssign()minusAssign()timesAssign()divAssign()remAssign()這些方法。那爲何官方文檔上會存在呢?這裏這裏不作詳解,可是我會在自定義重載操做符方法的時候給你們說明,請你們詳細的往下看,一些更高級的操做

2.三、位運算操做

位運算操做:即對一個數進行位移運算。關於這個操做符的重載函數,我在前面講解數據類型章節的時候已經講解過,這裏就很少作累述了。沒有看過的朋友請參見Kotlin——初級篇(三):數據類型詳解

2.四、區間操做

區間操做符:便是符號..。值得注意的是這個操做符在Java中是不存在的,且兩個操做數都是整型

操做符 表示 重載
a .. b a 到 b 中間的值 a.rangeTo(b)

這個操做符通常用於for循環中,在條件判斷中偶爾也會用到。

例:

val a = 1
val b = 5

// 操做符實現
val s = 3 in a .. b     // true,由於3在區間[1,5]以內
println("s = $s")
for (index in a .. b){
    print("index = $index \t")
}

// 操做符重載方式實現
val t = 3 in a.rangeTo(b)
println("t = $t")
for (index in a.rangeTo(b)){
    print("index = $index \t")
}

輸出結果爲:

s = true
index = 1 	index = 2 	index = 3 	index = 4 	index = 5 	
t = true
index = 1 	index = 2 	index = 3 	index = 4 	index = 5

固然了,這些實例都是極其簡單的。我在Kotlin——初級篇(四):控制語句講解這篇文章也是講到過的。

總結

關於操做符重載,這裏因爲篇幅過長的緣由,後面的比較操做符,以及inis、以及自定義操做符等都會在下一章講解。敬請期待...

這篇文章,主要講解了Kotlin中經常使用的操做符以及重載方法。其中的第一部分只是介紹了其概念,在第二節在纔開始講解了其用法及實例說明。重點在於二元操做中的複合運算一節,千萬不要被別人的博客和翻譯文檔所誤導。上面的實例都是我一個一個實驗事後才寫出來的。實踐出真理,否則我也不知道這個a += b等所 對應的a.plusAssign(b)等會這麼坑。

參考

這裏參考了別人翻譯的官方文檔
以及另一篇很好的博文

源代碼

若是各位大佬看了以後感受還闊以,就請各位大佬隨便star一下,您的關注是我最大的動力。
個人我的博客Jetictors
個人githubJetictors
個人掘金Jetictors

<p align = "center"> <h2 align="center">歡迎各位大佬進羣共同研究、探索 <br/> <h4 align="center">QQ羣號:497071402 <br/> <br/> <img src="https://user-gold-cdn.xitu.io/2017/12/30/160a5e3194215cdd?w=200&h=274&f=jpeg&s=68508"/> </p>

相關文章
相關標籤/搜索