基本運算符 (Basic Operators)
自從蘋果2014年發布Swift,到現在已經兩年多了,而Swift也來到了3.1版本。去年利用工作之余,共花了兩個多月的時間把官方的Swift編程指南看完。現在整理一下筆記,回顧一下以前的知識。有需要的同學可以去看官方文檔>>。
術語 (Terminology)
運算符有一元、二元和三元:
- 一元運算符只操作一個操作數(例如
-a
)。一元運算符寫在操作數的前面或者后面,例如!b
和c!
,并且運算符和操作數不能有空格。 - 二元運算符操作兩個操作數(例如
2 + 3
)。 - 三元運算符操作三個操作數。像C語言一樣,Swift只有一個三元運算符,
a ? b : c
。
賦值運算符 (Assignment Operator)
賦值運算符用來初始化變量的值,或者更新變量的值
let b = 10
var a = 5
a = b
// a現在等于10
如果賦值運算符右邊是一個有多個元素的多元組,多元組的元素可以一次性分解成多個常量或者變量:
let (x, y) = (1, 2)
// x等于1,y等于2
不同于C和OC,Swift中的賦值運算符本身不返回任何值。下面這個語句是非法的:
if x = y {
// 這是非法的,因為x=y不返回任何值
}
算術運算符 (Arithmetic Operators)
Swift支持下面這四個標準的算術運算符:
- 加 (
+
) - 減 (
-
) - 乘 (
*
) - 除 (
/
)
1 + 2 // 等于 3
5 - 3 // 等于 2
2 * 3 // 等于 6
10.0 / 2.5 // 等于 4.0
另外,+
可以用來拼接String
字符串:
"hello, " + "world" // 等于 "hello, world"
求余運算符 (Remainder Operator)
9 % 4 // 等于 1
為了得出a % b
的結果,%
這個求余運算符計算下面的等式,并返回remainder
:
a = (b * some multiplier(另外一個乘數)) + 余數
some multiplier
是a
和b
的最大公約數。
上面的計算方法同樣適用于負數:
-9 % 4 // 等于 -1
把-9
和4
代入那個公式:
-9
= (4
* -2
) + -1
所以返回-1
。
其實b
前面的符號可以忽略,也就意味著a % b
和a % -b
的返回值是相等的。
一元減號運算符 (Unary Minus Operator)
let three = 3
let minusThree = -3 // minusThree等于-3
let plusThree = -minusThree // plusThree等于3
一元加號運算符 (Unary Plus Operator)
let minusSix = -6
let alsoMinusSix = +minusSix // alsoMinusSix等于6
一元加號運算符不會改變操作數的值。但是為了保持對稱,在代碼中負數使用一元加號運算符,正數也加上一元加號運算符。
復合賦值運算符 (Compound Assignment Operators)
var a = 1
a += 2
// a 等于 3
a += 2
其實是a = a + 2
的簡寫。
注意:復合賦值運算符不會返回任何值,例如:我們不能這樣寫:let b = a += 2
。
比較運算符 (Comparison Operators)
Swift支持全部C語言的標準運算符:
- 等于 (
a == b
) - 不等于 (
a != b
) - 大于 (
a > b
) - 小于 (
a < b
) - 大于或等于 (
a >= b
) - 小于或等于 (
a <= b
)
注意:Swift還額外提供了恒等運算符 (identity operator) (===
和!==
),用來判斷兩個對象是否引用同一個實例。
所有的比較運算符都會返回一個Bool
值:
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")
}
// Prints "hello, world", because name is indeed equal to "world".
還可以用來比較多元組,只要多元組的元素個數相同,并且每個元素都是可比較的。例如,Int
和String
都是可以比較的,也就意味著多元組(Int, String)
也是可以比較的。相反,Bool
是不能比較的,所以元素中含有布爾值的多元組是不能比較的。
多元組在比較的時候,是從左到右一個一個比較,直到發現兩個參與比較的值不相等,那么這兩個不相等的元素的比較結果就作為兩個多元組的比較結果。如果每個元素都各自相等,那么這個多元組就相等:
(1, "zebra") < (2, "apple") // true 因為 1 is less than 2; "zebra" 和 "apple" 不用在比較
(3, "apple") < (3, "bird") // true 因為 3 等于 3, 并且 "apple" 小于 "bird"
(4, "dog") == (4, "dog") // true 因為 4 等于 4, 并且 "dog" 等于 "dog"
在上面的例子中,按照從左到右一個個比較的規則,因為1
小于2
,所以(1, "zebra")
小于(2, "apple")
,因為已經發現了兩個不相等的元素,后面的元素將不再比較,盡管zebra
大于apple
。然而,當發現兩個元素相等時,將會繼續往下比較。
注意:Swift標準庫只支持小于7個元素的多元組進行比較。如果多元組的元素大于或等于7個,我們必須自己實現比較運算符。
三元運算符 (Ternary Conditional Operator)
三元運算符是有三部分的比較特別的運算符,格式:question ? answer1: answer2
。是下面這個代碼的簡寫:
if question {
answer1
}
else {
answer2
}
例如下面這個例子:
let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight 等于 90
我們要避免使用三元運算符把多個判斷條件組合在一起,因為這會造成代碼很難讀懂。
空合并運算符 (Nil-Coalescing Opeartor)
使用空合并運算符(a ?? b
)來解包一個可選類型變量,如果a有值,返回a!
,如果為nil
,返回默認值b
。a
必須是一個可選類型,b
的類型必須a
包含的值類型相同。
空合并運算符其實是下面這個代碼的簡寫:
a != nil ? a! : b
下面舉個例子:
let defaultColor = "red"
var userDefinedColorName: String? // 默認是nil
var colorNameToUse = userDefinedColorName ?? defaultColor
// userDefinedColorName 為 nil,所以 colorNameToUse被設置為默認值 "red"
范圍運算符 (Range Operators)
閉合范圍運算符 (Closed Range Operator)
閉合范圍運算符(a...b
)定義了一個從a
到b
的范圍,并且包括a
和b
,a
的值不能大于b
。
當你想使用一個范圍的每一個值時,使用閉合運算符非常有用。例如:
for index in 1...5 {
print("\(index) 乘以 5 等于 \(index * 5)")
}
// 1 乘以 5 等于 5
// 2 乘以 5 等于 10
// 3 乘以 5 等于 15
// 4 乘以 5 等于 20
// 5 乘以 5 等于 25
半閉合運算符 (Half-Open Range Operator)
半閉合運算符(a..<b
)定義了一個從a
到b
的范圍,但是不包括b
,a
的值不能大于b
。如果a
等于b
,那么這個范圍就是空的。
在使用下標以0開始的的列表,例如數組,但是不包含數組的長度,使用半閉合運算符非常合適:
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print("Person \(i + 1) 是 \(names[i])")
}
// Person 1 是 Anna
// Person 2 是 called Alex
// Person 3 是 called Brian
// Person 4 是 called Jack
邏輯運算符 (Logical Operators)
Swift支持這三個標準的邏輯運算符:
- 邏輯非 (
!a
) - 邏輯與 (
a && b
) - 邏輯或 (
a || b
)
邏輯非運算符 (Logical NOT Operator)
邏輯非讓一個布爾值取反,true
變為false
,false
變為true
。
let allowedEntry = false
if !allowedEntry {
print("拒絕訪問")
}
// Prints "拒絕訪問"
邏輯與運算符 (Logical AND Operator)
邏輯與運算符(a && b
)兩邊的邏輯語句都為true
時,整個語句才是true
。如果有其中一個為false
,整個語句就為false
。實際上,只要第一個語句是false
,第二個語句就不會在計算了,因為第二個語句無論是true
還是false
都不可能把最終的結果改為true
。
let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "ACCESS DENIED"
邏輯或運算符 (Logical OR Operator)
邏輯或運算符兩邊的邏輯語句,只要有一個是true
,那整個語句就是true
。如果第一個語句是true
,第二個就不會再計算。
let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"
組合邏輯運算符 (Combining Logical Operators)
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"
在這個例子中,使用多個&&
和||
運算符來創建一個更長的復合語句。但是&&
和||
運算符還是僅僅操作兩個邏輯語句。上面的代碼可以這么讀:如果我們輸入了正確的門密碼并且通過了視網膜掃描,或者有門鑰匙,或者我們知道緊急覆蓋密碼,那么就允許進入。
明確的括號 (Explicit Parentheses)
在恰當的位置加上括號,增強代碼的易讀性:
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"
第二部分完。下個部分:【Swift 3.1】03 - 字符串和字符 (Strings and Characters)
如果有錯誤的地方,歡迎指正!謝謝!