運算符是檢查、改變、合并值的特殊符号或短語。例如,加号( + )将兩個數相加(如 let i = 1 + 2 )。更複雜的運算例⼦包括邏輯與
運算符 && (如 if enteredDoorCode && passedRetinaScan )。
Swift 支援大部分标準 C 語言的運算符,且為了減少常見編碼錯誤做了部分改進。如:指派符( = )不再有傳回值,這樣就消除了⼿
誤将判等運算符( == )寫成指派符導緻代碼錯誤的缺陷。算術運算符( + , - , * , / , % 等) 的結果會被檢測并禁止值溢出,以
此來避免儲存變量時由于變量大于或小于其類型所能承載的範圍時導緻的異常結果。當然允許你使用 Swift 的溢出運算符來實作
溢出。
Swift 還提供了 C 語言沒有的區間運算符,例如 a..<b 或 a...b ,這友善我們表達一個區間内的數值。 本章節隻描述了 Swift 中的
基本運算符,進階運算符這章會包含 Swift 中的⾼級運算符,及如何自定義運算符,及如何進⾏自定義類型的運算符重載。
術語
運算符分為一進制、二進制和三元運算符:
一進制運算符對單一操作對象操作(如 -a )。一進制運算符分前置運算符和後置運算符,前置運算符需緊跟在操作對象之前(如 !b ),後
置運算符需緊跟在操作對象之後(如 c! )。
二進制運算符操作兩個操作對象(如 2 + 3 ),是中置的,因為它們出現在兩個操作對象之間。
三元運算符操作三個操作對象,和 C 語⾔言一樣,Swift 隻有一個三元運算符,就是三目運算符( a ? b : c )。
受運算符影響的值叫操作數,在表達式 1 + 2 中,加号 + 是二進制運算符,它的兩個操作數是值 1 和 2 。
指派運算符
指派運算符( a = b ),表示用 b 的值來初始化或更新 a 的值:
let b = 10
var a = 5
a=b // a 現在等于 10
如果指派的右邊是一個元組,它的元素可以馬上被分解成多個常量或變量:
let (x, y) = (1, 2) // 現在 x 等于 1,y 等于 2
與 C 語言和 Objective-C 不同,Swift 的指派操作并不傳回任何值。是以下面的語句是無效的:
if x = y {
// 此句句錯誤,因為 x = y 并不不傳回任何值
}
通過将 if x = y 标記為無效語句,Swift 能幫你避免把 ( == )錯寫成( = )這類錯誤的出現。
算術運算符
Swift 中所有數值類型都支援基本的四則算術運算符:
加法( + ) 1 + 2 //等于 3
減法( - ) 5 - 3 //等于 2
乘法( * ) 2 * 3 //等于 6
除法( / ) 10.0 / 2.5 // 等于 4.0
與 C 語言和 Objective-C 不同的是,Swift 預設情況下不允許在數值運算中出現溢出情況。但是你可以使用 Swift 的溢出運算符
來實作溢出運算(如 a &+ b )。
加法運算符也可用于 String 的拼接:
"hello, " + "world" // 等于 "hello, world"
求餘運算符
求餘運算符( a % b )是計算 b 的多少倍剛剛好可以容⼊ a ,傳回多出來的那部分(餘數)。
注意
求餘運算符( % )在其他語⾔也叫取模運算符。但是嚴格說來,我們看該運算符對負數的操作結果,「求餘」比「取模」更合适
些。
我們來談談求餘是怎麼回事,計算 9 % 4 ,你先計算出 4 的多少倍會剛好可以容入 9 中:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL3lFRNhXVEJWcONDTwYVbiVHNHpleO1GTulzRilWO5xkNNh0YwIFSh9Fd4VGdsATMfd3bkFGazxyaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cWZwpmLykjM2AzNygTMyIzNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpeg)
你可以在 9 中放入兩個 4 ,那餘數是 1(用橙色标出)。
在 Swift 中可以表達為:
9 % 4 //等于1
為了得到 a % b 的結果, % 計算了以下等式,并輸出 餘數 作為結果:
a = ( b × 倍數 ) + 餘數
當 倍數 取最大值的時候,就會剛好可以容入 a 中。
把 9 和 4 代入等式中,我們得 1 :
9 = (4 × 2) + 1
同樣的方法,我們來計算 -9 % 4 :
-9%4 //等于-1
把 -9 和 4 代入等式, -2 是取到的最大整數:
-9 = (4 × -2) + -1
餘數是 -1 。
在對負數 b 求餘時, b 的符号會被忽略。這意味着 a % b 和 a % -b 的結果是相同的。
一進制負号運算符
數值的正負号可以使用字首 - (即一進制負号符)來切換:
let three = 3
let minusThree = -three // minusThree 等于 -3
let plusThree = -minusThree // plusThree 等于 3, 或 "負負3"
一進制負号符( - )寫在操作數之前,中間沒有空格。
一進制正号運算符
一進制正号符( + )不做任何改變的傳回操作數的值:
let minusSix = -6
let alsoMinusSix = +minusSix // alsoMinusSix 等于 -6
雖然一進制正号符什麼都不會改變,但當你在使用一進制負号來表達負數時,你可以使用一進制正号來表達正數,如此你的代碼會具有
對稱美。
組合指派運算符
如同 C 語言,Swift 也提供把其他運算符和指派運算( = )組合的組合指派運算符,組合加運算( += )是其中一個例子:
var a = 1
a += 2 //a 現在是 3
表達式 a += 2 是 a = a + 2 的簡寫,一個組合加運算就是把加法運算和指派運算組合進一個運算符⾥,同時完成兩個運算任務。
注意
複合指派運算沒有傳回值, let b = a += 2 這類代碼是錯誤的。這不同于上面提到的自增和自減運算符。
比較運算符
所有标準 C 語言中的比較運算符都可以在 Swift 中使用:
等于( a == b )
不等于( a!=b )
大于( a > b )
小于( a < b )
大于等于( a>=b )
小于等于( a<=b )
注意
Swift 也提供恒等( === )和不恒等( !== )這兩個比較符來判斷兩個對象是否引用同一個對象實例。更多細節在類與結構章節的
IdentityOperators 部分。
每個比較運算都傳回了一個辨別表達式是否成立的布爾值:
1 == 1 //true, 因為 1 等于 1
2 != 1 //true, 因為 2 不等于 1
2 > 1 //true, 因為 2 大于 1
1 < 2 //true, 因為 1 小于2
1 >= 1 //true, 因為 1 大于等于 1
2 <= 1 //false, 因為 2 并不小于等于 1
比較運算多用于條件語句,如 if 條件:
let name = "world"
if name == "world" {
print("hello, world")
} else {
print("I'm sorry \(name), but I don't recognize you")
}
// 輸出“hello, world", 因為 `name` 就是等于 "world”
如果兩個元組的元素相同,且長度相同的話,元組就可以被比較。比較元組⼤小會按照從左到右、逐值比較的方式,直到發現有
兩個值不等時停止。如果所有的值都相等,那麼這一對元組我們就稱它們是相等的。例如:
(1, "zebra") < (2, "apple") // true,因為 1 ⼩于 2
(3, "apple") < (3, "b") // true,因為 3 等于 3,但是 apple 小于 b,字元串比較應該是字母ASCII 逐個比較 a < b
(4, "dog") == (4, "dog") // true,因為 4 等于 4,dog 等于 dog
在上面的例子中,你可以看到,在第一⾏中從左到右的比較⾏為。因為 1 小于 2 ,是以 (1, "zebra") 小于 (2, "apple") ,不管元組
剩下的值如何。是以 "zebra" 大于 "apple" 對結果沒有任何影響,因為元組的比較結果已經被第一個元素決定了。不過,當元組
的第一個元素相同時候,第二個元素将會用作比較。第二⾏和第三行代碼就發生了這樣的比較。
當元組中的元素都可以被比較時,你也可以使用這些運算符來比較它們的⼤小。例如,像下⾯面展示的代碼,你可以比較兩個類
型為(String, Int) 的元組,因為 Int 和 String 類型的值可以比較。相反, Bool 不能被比較,也意味着存有布爾類型的元組不能被
比較。
("blue", -1) < ("purple", 1) // 正常,⽐較的結果為 true
("blue", false) < ("purple", true) // 錯誤,因為 < 不能比較布爾類型
注意
Swift 标準庫隻能比較七個以内元素的元組比較函數。如果你的元組元素超過七個時,你需要⾃己實作比較運算符。
三元運算符
三元運算符的特殊在于它是有三個操作數的運算符,它的形式是 問題 ? 答案 1 : 答案 2 。它簡潔地表達根據 問題 成立與否作出二
選⼀的操作。如果 問題 成立,傳回 答案 1 的結果;反之傳回 答案 2 的結果。
三元運算符是以下代碼的縮寫形式:
if question {
answer1
} else {
answer2
}
這里有個計算表格行高的例子。如果有表頭,那⾏高應比内容高度要高出 50 點;如果沒有表頭,隻需高出 20 點:
let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20) // rowHeight 現在是 90
上⾯的寫法⽐下面的代碼更簡潔:
let contentHeight = 40
let hasHeader = true
var rowHeight = contentHeight
if hasHeader {
rowHeight = rowHeight + 50
} else {
rowHeight = rowHeight + 20
}
// rowHeight 現在是 90
第一段代碼例子使用了三元運算,是以一行代碼就能讓我們得到正确答案。這比第二段代碼簡潔得多,無需将rowHeight 定義成
變量,因為它的值無需在 if 語句中改變。
三元運算為二選一場景提供了一個⾮常便捷的表達形式。不過需要注意的是,濫⽤三元運算符會降低代碼可讀性。是以我們應避
免在一個複合語句中使用多個三元運算符。