Swift語言指南(九)--基本運算符

運算符(operator)是用來檢查,改變或合併值的一種特殊符號或短語。例如,加號運算符讓兩個數字相加(如:let i = 1 + 2),還有些更復雜的運算符,如邏輯與運算符(&&)(如:if enteredDoorCode && passedRetinaScan)和自增運算符(++i)(將 i 的值加 1 的便捷寫法)。git

Swift 支持標準C語言的大多數運算符,而且改進了一些特性以規避常見的代碼錯誤。賦值運算符(=)是沒有返回值的,這樣是爲了不在使用等於運算符(==)時誤用了賦值運算符(=)。算術運算符(+-*/% 等等)會偵測並阻止值溢出,可避免在運算時超出存儲類型的值域範圍(比實際運算結果大或小,或不精準--Joe.Huang)。若是須要支持溢出行爲,能夠選用 Swift 的溢出運算符,詳情可見 溢出運算符(後面章節譯到)。github

與C語言不一樣的是,Swift 容許對浮點數求餘(%)。Swift 還提供了C語言所沒有的兩個區間運算符(a..b和a...b),做爲表示值域範圍的便捷寫法。算法

本章介紹 Swift 中的經常使用運算符。高級運算符 (後面章節譯到) 一章涵蓋了 Swift 中的高級運算符,並講解了如何自定義運算符,以及讓標準運算符支持自定義類型的運算。數組

 

運算符術語less

運算符分爲一元,二元,三元運算符:ide

· 一元運算符unary operator)對單個目標進行運算(如 -a)。一元運算符前綴unary prefix operator)緊跟運算目標以前(如 !b),而一元運算符後綴unary postfix operator)則緊跟運算目標以後(如 i++)。post

· 二元運算符binary operator)對兩個目標進行運算(如 2 + 3),它們屬於中綴infix)運算符,由於(運算符號)出如今兩個運算目標之間。測試

· 三元運算符ternary operator)對三個目標進行運算。與 C 語言同樣,Swift 只有一個三元運算符:三元條件運算符( a ? b : c)。ui

運算符操做的值稱爲運算元operands)。在表達式 1 + 2 中,+ 符號是二元運算符,它的兩個運算元爲值 1與值 2this

 

賦值運算符

賦值運算符assignment operator,a = b)用 b 的值初始化或更新 a 的值:

1 let b = 10
2 var a = 5
3 a = b
4 // a is now equal to 10
5 //a如今等於10

若是賦值語句的右側是一個包含多個值的元組,元組的元素可一次性用多個常量或變量分解提取出來(上一章講解元組時提到過度解元組值的方法--Joe.Huang):

1 let (x, y) = (1, 2)
2 // x is equal to 1, and y is equal to 2
3 //x等於1,y等於2

與 C 或 Objective-C 語言的賦值運算符不一樣,Swift 語言的賦值運算符自己沒有返回值。所以下面的語句不正確:

1 if x = y {
2     // this is not valid, because x = y does not return a value
3     // 這是無效的,由於 x = y 不會返回一個值 (x==y才能夠,--Joe.Huang)
4 }

該特性可避免在使用等於運算符(==)時誤用了賦值運算符(=)。經過否定 if x = y 的有效性,Swift 將幫助你規避代碼中出現這樣的錯誤。

 

算術運算符

Swift支持對全部數字類型使用四種標準算術運算符:

· 加:+

· 減:-

· 乘:*

· 除:/

1 1 + 2       //  等於3
2 5 - 3       //  等於2
3 2 * 3       //  等於6
4 10.0 / 2.5  //  等於4.0

與 C / Objective-C 語言的算術運算符不一樣,Swift 的算術運算符默認不容許值溢出。若是須要支持溢出行爲,能夠選用 Swift 的溢出運算符(如,a &+ b),詳情可見 溢出運算符(後面章節譯到)。

加號運算符也支持 String 拼接:

"hello, " + "world"  // 等於 "hello, world"

能夠將兩個 Character (字符,Unicode字符--Joe.Huang)值相加,或將一個 Character 值與一個 String 值相加,獲得新的 String 值:

1 let dog: Character = ""
2 let cow: Character = ""
3 let dogCow = dog + cow
4 // dogCow 等於 ""

 詳見 字符與字符串拼接 (後面章節譯到):

 

求餘運算符

求餘運算符remainder operatora % b)求出 a 包含多少個 b,並返回剩餘的值(即整除後的餘數 remainder)。

 注:

求餘運算符(%)在其餘語言中也稱做求模運算符modulo operator)。但對負數的運算結果代表:Swift 語言的實現是嚴格的求餘操做,而非求模操做。

求餘運算符的原理以下。 要計算 9 % 4,首先要求出 9 裏面包含多少個 4

 

如圖所示,9 裏面包含兩個 4,餘數是 1 (橙色部分)。 

Swift中的寫法以下:

9 % 4  //等於 1

要求出 a % b 的結果,% 運算符會計算下面的等式,並將餘數做爲輸出結果返回:

a = (b × some multiplier) + remainder

其中 some multipliera 中能裝下 b 的最大數目。

94 代入等式:

9 = (4 × 2) + 1

a 爲負數時,求餘方法不變:

-9 % 4   // 等於 -1

-94 代入等式:

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

獲得的餘數值爲-1

b 爲負值(-b)時,b 的負號將被忽略。所以 a % ba % -b 老是返回相同的結果。

 

浮點數的求餘計算

與 C / Objective-C 語言的餘數運算符不一樣,Swift 的餘數運算符還能對浮點數進行求餘計算:

8 % 2.5   // equals 0.5

上例中,8 除以 2.5 等於 3,餘數爲 0.5,所以餘數運算符返回 Double 型的值 0.5

 

自增與自減運算符

與 C 語言相似,Swift 也提供了自增運算符++)與自減運算符--),做爲將數字變量的值加上或減去 1 的便捷寫法。任何整型或浮點型的變量均可以使用這兩個運算符。

1 var i = 0
2 ++i      // i 如今等於 1

每次調用 ++i 時,i 的值就會增長 1。本質上,++i 就是 i = i + 1 的便捷寫法。相似地,--i 也至關於 i = i - 1

++-- 兩對符號能夠做爲前綴或後綴運算符使用。++ii++ 都可用來將 i 的值加 1。相似地,--i i-- 都可用來將 i 的值減去 1

注意,這些運算符不只會改變 i 的值,還會返回一個值。若是你只須要將自增或自減後的值存放在 i 中,那你能夠忽略運算符的返回值。但若是你確實要用到返回值,要注意前綴及後綴運算符返回值的差別,規則以下:

· 若是運算符在變量名前面,先改變它的值,再返回其值。

· 若是運算符在變量名後面,先返回原值,再改變它的值。

如例:

1 var a = 0
2 let b = ++a
3 // a 和 b 如今都等於 1,即改變a的值,再返回
4 let c = a++
5 // a 如今等於 2, 但 c 仍是自增前的值 1,即先返回的a的原值,再改變其值

在上例中,let b = ++a 先增長 a 的值(加1),而後才返回它的值。所以 ab 都等於新的值 1

可是,let c = a++ 先返回 a 的原值(加1以前的值)而後才增長 a 的值。即 c 獲得了原值 1,而後 a 被更新爲新值 2

除非你須要利用 i++ 的這一特性,建議你在全部狀況下都使用 ++i--i,由於它們先修改 i 再返回修改後的值的動做更符合邏輯。

 

一元減號運算符

數值前加上前綴 - ,這個前綴運算符 - 就稱爲一元減號運算符:

1 let three = 3
2 let minusThree = -three       // minusThree 等於 -3
3 let plusThree = -minusThree   // plusThree 等於 3, 或等於 "減去 minusThree"

一元減號運算符(-)緊靠所要操做的值以前,無需任何空格。

 

一元加號運算符

一元加號運算符(+)直接返回所操做的值,不做任何處理:

1 let minusSix = -6
2 let alsoMinusSix = +minusSix  // alsoMinusSix 等於 -6

儘管一元加號運算符實際上不做任何運算,代碼中仍然能夠用它(提供語義信息,一元減號運算符表示負數,一元加號運算符表示正數--Joe.Huang)與表示負數的一元減號運算符造成對比。

 

複合賦值運算符

與 C 語言相似,Swift 也提供複合賦值運算符compound assignment operator將賦值運算符(=)與其餘運算組合起來使用。例如加法賦值運算符(addition assignment operator+=):

1 var a = 1
2 a += 2
3 // a 等於 3

上例中的表達式 a = a + 2 簡寫爲 a += 2,加法和賦值兩項操做組合爲一個單項操做,執行時很是高效。

注:

複合賦值操做沒有返回值,即,你不能寫:let b = a += 2,這一操做與前面所提到的自增自減操做是不一樣的。

複合賦值運算符的完整列表可在 表達式 一章中找到(後面章節譯到)。

 

比較運算符

Swift支持標準C 的比較運算符:

      等於   (a == b)
   不等於   (a != b)
      大於   (a > b)
      小於   (a < b)
 大於等於  (a >= b)
 小於等於  (a <= b)

注:

Swift還提供了恆等(===)和不恆等(!==)兩個鑑別運算符,你能夠用它測試兩個對象是否引用了同一個對象實例。更多詳情請參考 類和結構 一章(後面章節譯到)。

每一個比較運算符都會返回一個 Bool 值,檢測表達式是否成立:

1 1 == 1   // true, 由於 1 等於 1
2 2 != 1   // true, 由於 2 不等於 1
3 2 > 1    // true, 由於 2 大於 1
4 1 < 2    // true, 由於 1 小於 2
5 1 >= 1   // true, 由於 1 大於等於 1
6 2 <= 1   // false, 由於 2 大於等於 1

比較運算符常見於條件表達式中,如 if 條件句:

1 let name = "world"
2 if name == "world" {
3     println("hello, world")
4 } else {
5     println("I'm sorry \(name), but I don't recognize you")
6     //輸出(」對不起\name,我不認識你「)
7 }
8 // prints "hello, world", because name is indeed equal to "world"
9 //輸出 "hello world",由於 name 確實等於"world"

if 語句的更多介紹,詳見 流程控制 一章(後面章節譯到)。

 

三元條件運算符

三元運算符是一種特殊運算符,由三個部分組成,表現形式爲:question ? answer1 : answer2。它是一種求值簡寫:根據 question 是否成立,從兩個表達式中取出一個並求值。

若是 question 成立,則計算 answer1 的結果並返回其值;不然計算 answer2 並返回其值。

三元條件運算符是以下代碼的縮寫:

1 if question {
2     answer1
3 } else {
4     answer2
5 }

下面的例子將計算表格某行的像素高度。若是該行有表頭,則行高應比內容高度高 50 個像素;若是沒有表頭,則只高出 20 個像素:

1 let contentHeight = 40
2 let hasHeader = true
3 let rowHeight = contentHeight + (hasHeader ? 50 : 20)
4 // rowHeight(行高) 等於 90

上例即是以下代碼的縮寫:

1 let contentHeight = 40
2 let hasHeader = true
3 var rowHeight = contentHeight
4 if hasHeader {
5     rowHeight = rowHeight + 50
6 } else {
7     rowHeight = rowHeight + 20
8 }
9 // rowHeight(行高) 等於 90

使用三元條件運算符的例子說明,能夠僅用一行代碼就將行高設爲正確的值。這比(不用三元運算符的)第二個例子簡潔得多,而且行高(rowHeight)無需定義爲變量,由於再也不須要用 if 語句修改其值。

三元條件運算符提供了二選一的高效寫法。但使用三元條件運算符應當心。若是過分使用,其簡明性可能致使代碼可讀性差。應避免將多個三元條件運算符組合在同一個語句中。

 

區間運算符

Swift有兩個區間運算法,是表示值域的簡便寫法。

 

閉區間運算符

區間運算符(a...b)定義了 ab 的區間範圍,包括 a 在內。

閉區間運算符在須要遍歷某區間內全部的值時頗有用,如在 for-in 循環中使用:

1 for index in 1...5 {
2     println("\(index) times 5 is \(index * 5)")
3     //輸出("\(index)乘以 5 得 (\index * 5)")
4 }
5 // 1 乘以 5 得 5
6 // 2 乘以 5 得 10
7 // 3 乘以 5 得 15
8 // 4 乘以 5 得 20
9 // 5 乘以 5 得 25

for-in 語句的更多介紹,詳見 流程控制 一章(後面章節譯到)。

 

半閉區間運算符

半閉區間運算符(a..b)定義了從 ab 的區間,但 b 不包括在內。說它是半閉區間,是由於第一個值包含在區間內,但最後一個值在區間外。

半閉區間在處理從 0 開始計數的列表時有用,如遍歷數組,可從 0 數到列表的長度(但不包括長度值自己):

1 let names = ["Anna", "Alex", "Brian", "Jack"]
2 let count = names.count
3 for i in 0..count {
4     println("Person \(i + 1) is called \(names[i])")
5 }
6 // Person 1 名字是 Anna
7 // Person 2 名字是 Alex
8 // Person 3 名字是 Brian
9 // Person 4 名字是 Jack

注意,數組包含四個元素,但由於是半閉區間,因此 0..count 只數到 3(數組中最後一個元素的索引號)。數組更多信息詳見 數組 一章(後面章節譯到)

 

邏輯運算符

邏輯運算符是對布爾邏輯值 truefalse 的組合操做,Swift 支持 C 及其衍生語言的三種標準邏輯運算符:

· 邏輯非(!a

· 邏輯與(a && b

· 邏輯或(a || b

邏輯非運算符

邏輯非運算符對布爾值取反,即 true 變成 falsefalse 變成true

邏輯非運算符是一個前綴運算符,緊跟在所操做值的前面,沒有任何空格符。能夠理解爲"非",以下例:

1 let allowedEntry = false
2 if !allowedEntry {
3     println("ACCESS DENIED")
4 }
5 // prints "ACCESS DENIED"
6 //輸出」ACCESS DENIED「

代碼中的 if !allowedEntry 能夠理解爲「若是不容許進入」。隨後的下一行代碼僅當「不容許進入」成立時纔會執行;即 allowedEntry 爲 false 時才執行。

如上例,布爾值常量及變量的名稱應謹慎選擇命名,方可確保代碼簡明又具可讀性,同時也應避免使用雙重否認或引發混淆的邏輯語句。

 

邏輯與運算符

a && b)構造這樣的邏輯表達式:運算符兩側的值均爲 true,整個表達式的求值結果才爲 true

 

若是有一個值爲 false,整個表達式便爲 false。事實上,若是第一個值false,第二個值將不執行求值運算,由於不管它爲什麼值,整個表達式的值都不可能等於 true。這也被稱爲短路求值short-circuit evaluation)。

下面的例子驗證兩個值,當兩個值都爲 true 時才能訪問:

 

1 let enteredDoorCode = true
2 let passedRetinaScan = false
3 if enteredDoorCode && passedRetinaScan {
4     println("Welcome!")
5 } else {
6     println("ACCESS DENIED")
7 }
8 // prints "ACCESS DENIED"  輸出"ACCESS DENIED"

 

邏輯或運算符

a || b)屬於中綴運算符,由兩個連續的豎線構成。它用來構造這樣的表達式:當兩個值中有一個爲 true時,整個表達式爲 true

與前面的邏輯與運算符同樣,邏輯或運算符在檢測它的兩個表達式時,也使用「短路求值」法。只要邏輯或表達式左側爲 true,其右側將不執行求值運算,由於這時右側的值對整個表達式的結果再也不有影響。

下例中,第一個 Bool 值(hasDoorKey)爲 false,但第二個值(knowOverridePassword)爲 true。由於有一個值爲 true,因此整個表達式的求值結果也爲 true,所以容許訪問:

1 let hasDoorKey = false
2 let knowsOverridePassword = true
3 if hasDoorKey || knowsOverridePassword {
4     println("Welcome!")
5 } else {
6     println("ACCESS DENIED")
7 }
8 // prints "Welcome!"  輸出"Welcome!"

 

組合使用邏輯運算符

能夠將多個邏輯運算符組合起來構成一個較長的複合表達式。

1if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
2     println("Welcome!")
3 } else {
4     println("ACCESS DENIED")
5 }
6 // prints "Welcome!"  輸出"Welcome!"

本例使用多個 &&|| 運算符構成一條較長的複合表達式。不過,&&|| 運算符操做的仍然是兩個值,所以該組合表達式其實是由三個較短的表達式連立而成。它能夠這樣理解:

若是咱們輸入了正確的門禁密碼、而且經過了視網膜掃描;或者若是咱們有門鑰匙;或者若是咱們知道緊急的備用密碼,則容許訪問。

根據 enteredDoorCodepassedRetinaScanhasDoorKey 三個常量推算,前兩個小表達式的值均爲 false。不過咱們知道緊急的備用密碼(knowsOverridePassword 爲 true),所以整個複合表達式的求值結果仍然爲 true

 

顯式括號

有時(從語法來看)括號並非必需的,但加上括號卻頗有用,它可讓複雜表達式的易於閱讀。 在上例中,爲組合表達式的第一部分加上括號,可以使其意圖更明顯:

1 if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
2     println("Welcome!")
3 } else {
4     println("ACCESS DENIED")
5 }
6 // prints "Welcome!"  //輸出"Welcome!"

括號將前兩個值與其餘值分隔開來,使其做爲總體邏輯中的一種可選狀態的意思更加明顯。組合表達式的結果不會改變,但對讀者而言,總體意圖更加清晰。可讀性老是優先於簡潔性;應儘量在合適的地方使用括號,使你的邏輯更加明晰。

 

 

謝謝,Swifter-QQ羣:362232993,同好者進~ 

Fork:https://github.com/Joejo/Swift-lesson-for-chinese

相關文章
相關標籤/搜索