【Swift 3.1】02 - 基本運算符 (Basic Operators)

基本運算符 (Basic Operators)

自從蘋果2014年發布Swift,到現在已經兩年多了,而Swift也來到了3.1版本。去年利用工作之余,共花了兩個多月的時間把官方的Swift編程指南看完。現在整理一下筆記,回顧一下以前的知識。有需要的同學可以去看官方文檔>>。


術語 (Terminology)

運算符有一元、二元和三元:

  • 一元運算符只操作一個操作數(例如-a)。一元運算符寫在操作數的前面或者后面,例如!bc!,并且運算符和操作數不能有空格。
  • 二元運算符操作兩個操作數(例如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 multiplierab的最大公約數。

上面的計算方法同樣適用于負數:

-9 % 4 // 等于 -1

-94代入那個公式:

-9 = (4 * -2) + -1

所以返回-1。

其實b前面的符號可以忽略,也就意味著a % ba % -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".

還可以用來比較多元組,只要多元組的元素個數相同,并且每個元素都是可比較的。例如,IntString都是可以比較的,也就意味著多元組(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,返回默認值ba必須是一個可選類型,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)定義了一個從ab的范圍,并且包括ab,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)定義了一個從ab的范圍,但是不包括ba的值不能大于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變為falsefalse變為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)


如果有錯誤的地方,歡迎指正!謝謝!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容