在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ 基本運(yùn)算符(Basic Operators)
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪問(wèn)控制和 protected
語(yǔ)句(Statements)
模式(Patterns)
WWDC 里面的那個(gè)“大炮打氣球”
關(guān)于語(yǔ)言參考(About the Language Reference)
語(yǔ)法總結(jié)(Summary of the Grammar)
嵌套類型
類型(Types)
Swift 初見(jiàn)(A Swift Tour)
泛型
枚舉(Enumerations)
高級(jí)運(yùn)算符
繼承
析構(gòu)過(guò)程
關(guān)于 Swift(About Swift)
訪問(wèn)控制
類和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語(yǔ)言指針友好合作
協(xié)議
屬性(Properties)
可選類型完美解決占位問(wèn)題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類型與引用類型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類型不是夢(mèng)-白話 Swift 類型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類型轉(zhuǎn)換
構(gòu)造過(guò)程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

基本運(yùn)算符(Basic Operators)


1.0 翻譯:XieLingWang 校對(duì):EvilCome

2.0 翻譯+校對(duì):JackAlan

2.1 校對(duì):shanks

2.2 翻譯+校對(duì):Cee 校對(duì):SketchK,2016-05-11 3.0.1,shanks,2016-11-11

4.0 翻譯+校對(duì):kemchenj

4.1 翻譯+校對(duì):mylittleswift

本頁(yè)包含內(nèi)容:

運(yùn)算符是檢查、改變、合并值的特殊符號(hào)或短語(yǔ)。例如,加號(hào)(+)將兩個(gè)數(shù)相加(如 let i = 1 + 2)。更復(fù)雜的運(yùn)算例子包括邏輯與運(yùn)算符 &&(如 if enteredDoorCode && passedRetinaScan)。

Swift 支持大部分標(biāo)準(zhǔn) C 語(yǔ)言的運(yùn)算符,且改進(jìn)許多特性來(lái)減少常規(guī)編碼錯(cuò)誤。如:賦值符(=)不返回值,以防止把想要判斷相等運(yùn)算符(==)的地方寫(xiě)成賦值符導(dǎo)致的錯(cuò)誤。算術(shù)運(yùn)算符(+,-,*,/% 等)會(huì)檢測(cè)并不允許值溢出,以此來(lái)避免保存變量時(shí)由于變量大于或小于其類型所能承載的范圍時(shí)導(dǎo)致的異常結(jié)果。當(dāng)然允許你使用 Swift 的溢出運(yùn)算符來(lái)實(shí)現(xiàn)溢出。詳情參見(jiàn)溢出運(yùn)算符

Swift 還提供了 C 語(yǔ)言沒(méi)有的區(qū)間運(yùn)算符,例如 a..<ba...b,這方便我們表達(dá)一個(gè)區(qū)間內(nèi)的數(shù)值。

本章節(jié)只描述了 Swift 中的基本運(yùn)算符,高級(jí)運(yùn)算符這章會(huì)包含 Swift 中的高級(jí)運(yùn)算符,及如何自定義運(yùn)算符,及如何進(jìn)行自定義類型的運(yùn)算符重載。

術(shù)語(yǔ)

運(yùn)算符分為一元、二元和三元運(yùn)算符:

  • 一元運(yùn)算符對(duì)單一操作對(duì)象操作(如 -a)。一元運(yùn)算符分前置運(yùn)算符和后置運(yùn)算符,前置運(yùn)算符需緊跟在操作對(duì)象之前(如 !b),后置運(yùn)算符需緊跟在操作對(duì)象之后(如 c!)。
  • 二元運(yùn)算符操作兩個(gè)操作對(duì)象(如 2 + 3),是中置的,因?yàn)樗鼈兂霈F(xiàn)在兩個(gè)操作對(duì)象之間。
  • 三元運(yùn)算符操作三個(gè)操作對(duì)象,和 C 語(yǔ)言一樣,Swift 只有一個(gè)三元運(yùn)算符,就是三目運(yùn)算符(a ? b : c)。

受運(yùn)算符影響的值叫操作數(shù),在表達(dá)式 1 + 2 中,加號(hào) + 是二元運(yùn)算符,它的兩個(gè)操作數(shù)是值 12。

賦值運(yùn)算符

賦值運(yùn)算符a = b),表示用 b 的值來(lái)初始化或更新 a 的值:

let b = 10
var a = 5
a = b
// a 現(xiàn)在等于 10

如果賦值的右邊是一個(gè)多元組,它的元素可以馬上被分解成多個(gè)常量或變量:

let (x, y) = (1, 2)
// 現(xiàn)在 x 等于 1,y 等于 2

與 C 語(yǔ)言和 Objective-C 不同,Swift 的賦值操作并不返回任何值。所以以下陳述時(shí)無(wú)效的:

if x = y {
    // 此句錯(cuò)誤,因?yàn)?x = y 并不返回任何值
}

這個(gè)特性使你無(wú)法把(==)錯(cuò)寫(xiě)成(=),由于 if x = y 是無(wú)效的,Swift 能幫你避免此類錯(cuò)誤發(fā)生。

算術(shù)運(yùn)算符

Swift 中所有數(shù)值類型都支持了基本的四則算術(shù)運(yùn)算符

  • 加法(+
  • 減法(-
  • 乘法(*
  • 除法(/
1 + 2       // 等于 3
5 - 3       // 等于 2
2 * 3       // 等于 6
10.0 / 2.5  // 等于 4.0

與 C 語(yǔ)言和 Objective-C 不同的是,Swift 默認(rèn)情況下不允許在數(shù)值運(yùn)算中出現(xiàn)溢出情況。但是你可以使用 Swift 的溢出運(yùn)算符來(lái)實(shí)現(xiàn)溢出運(yùn)算(如 a &+ b)。詳情參見(jiàn)溢出運(yùn)算符。

加法運(yùn)算符也可用于 String 的拼接:

"hello, " + "world"  // 等于 "hello, world"

求余運(yùn)算符

求余運(yùn)算符a % b)是計(jì)算 b 的多少倍剛剛好可以容入 a,返回多出來(lái)的那部分(余數(shù))。

注意

求余運(yùn)算符(%)在其他語(yǔ)言也叫取模運(yùn)算符。但是嚴(yán)格說(shuō)來(lái),我們看該運(yùn)算符對(duì)負(fù)數(shù)的操作結(jié)果,「求余」比「取?!垢线m些。

我們來(lái)談?wù)勅∮嗍窃趺椿厥?,?jì)算 9 % 4,你先計(jì)算出 4 的多少倍會(huì)剛好可以容入 9 中:

Art/remainderInteger_2x.png

你可以在 9 中放入兩個(gè) 4,那余數(shù)是 1(用橙色標(biāo)出)。

在 Swift 中可以表達(dá)為:

9 % 4    // 等于 1

為了得到 a % b 的結(jié)果,% 計(jì)算了以下等式,并輸出 余數(shù)作為結(jié)果:

a = (b × 倍數(shù)) + 余數(shù)

當(dāng) 倍數(shù)取最大值的時(shí)候,就會(huì)剛好可以容入 a 中。

94 代入等式中,我們得 1

9 = (4 × 2) + 1

同樣的方法,我們來(lái)計(jì)算 -9 % 4

-9 % 4   // 等于 -1

-94 代入等式,-2 是取到的最大整數(shù):

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

余數(shù)是 -1。

在對(duì)負(fù)數(shù) b 求余時(shí),b 的符號(hào)會(huì)被忽略。這意味著 a % ba % -b 的結(jié)果是相同的。

一元負(fù)號(hào)運(yùn)算符

數(shù)值的正負(fù)號(hào)可以使用前綴 -(即一元負(fù)號(hào)符)來(lái)切換:

let three = 3
let minusThree = -three       // minusThree 等于 -3
let plusThree = -minusThree   // plusThree 等于 3, 或 "負(fù)負(fù)3"

一元負(fù)號(hào)符(-)寫(xiě)在操作數(shù)之前,中間沒(méi)有空格。

一元正號(hào)運(yùn)算符

一元正號(hào)符+)不做任何改變地返回操作數(shù)的值:

let minusSix = -6
let alsoMinusSix = +minusSix  // alsoMinusSix 等于 -6

雖然一元正號(hào)符什么都不會(huì)改變,但當(dāng)你在使用一元負(fù)號(hào)來(lái)表達(dá)負(fù)數(shù)時(shí),你可以使用一元正號(hào)來(lái)表達(dá)正數(shù),如此你的代碼會(huì)具有對(duì)稱美。

組合賦值運(yùn)算符

如同 C 語(yǔ)言,Swift 也提供把其他運(yùn)算符和賦值運(yùn)算(=)組合的組合賦值運(yùn)算符,組合加運(yùn)算(+=)是其中一個(gè)例子:

var a = 1
a += 2
// a 現(xiàn)在是 3

表達(dá)式 a += 2a = a + 2 的簡(jiǎn)寫(xiě),一個(gè)組合加運(yùn)算就是把加法運(yùn)算和賦值運(yùn)算組合成進(jìn)一個(gè)運(yùn)算符里,同時(shí)完成兩個(gè)運(yùn)算任務(wù)。

注意

復(fù)合賦值運(yùn)算沒(méi)有返回值,let b = a += 2 這類代碼是錯(cuò)誤。這不同于上面提到的自增和自減運(yùn)算符。

更多 Swift 標(biāo)準(zhǔn)庫(kù)運(yùn)算符的信息,請(qǐng)看運(yùn)算符聲明。 ?

比較運(yùn)算符(Comparison Operators)

所有標(biāo)準(zhǔn) C 語(yǔ)言中的比較運(yùn)算符都可以在 Swift 中使用:

  • 等于(a == b
  • 不等于(a != b
  • 大于(a > b
  • 小于(a < b
  • 大于等于(a >= b
  • 小于等于(a <= b

注意

Swift 也提供恒等(===)和不恒等(!==)這兩個(gè)比較符來(lái)判斷兩個(gè)對(duì)象是否引用同一個(gè)對(duì)象實(shí)例。更多細(xì)節(jié)在類與結(jié)構(gòu)

每個(gè)比較運(yùn)算都返回了一個(gè)標(biāo)識(shí)表達(dá)式是否成立的布爾值:

1 == 1   // true, 因?yàn)?1 等于 1
2 != 1   // true, 因?yàn)?2 不等于 1
2 > 1    // true, 因?yàn)?2 大于 1
1 < 2    // true, 因?yàn)?1 小于2
1 >= 1   // true, 因?yàn)?1 大于等于 1
2 <= 1   // false, 因?yàn)?2 并不小于等于 1

比較運(yùn)算多用于條件語(yǔ)句,如 if 條件:

let name = "world"
if name == "world" {
    print("hello, world")
} else {
    print("I'm sorry \(name), but I don't recognize you")
}
// 輸出 "hello, world", 因?yàn)?`name` 就是等于 "world"

關(guān)于 if 語(yǔ)句,請(qǐng)看控制流。

如果兩個(gè)元組的元素相同,且長(zhǎng)度相同的話,元組就可以被比較。比較元組大小會(huì)按照從左到右、逐值比較的方式,直到發(fā)現(xiàn)有兩個(gè)值不等時(shí)停止。如果所有的值都相等,那么這一對(duì)元組我們就稱它們是相等的。例如:

(1, "zebra") < (2, "apple")   // true,因?yàn)?1 小于 2
(3, "apple") < (3, "bird")    // true,因?yàn)?3 等于 3,但是 apple 小于 bird
(4, "dog") == (4, "dog")      // true,因?yàn)?4 等于 4,dog 等于 dog

在上面的例子中,你可以看到,在第一行中從左到右的比較行為。因?yàn)?1 小于 2,所以 (1, "zebra") 小于 (2, "apple"),不管元組剩下的值如何。所以 "zebra" 大于 "apple" 對(duì)結(jié)果沒(méi)有任何影響,因?yàn)樵M的比較結(jié)果已經(jīng)被第一個(gè)元素決定了。不過(guò),當(dāng)元組的第一個(gè)元素相同時(shí)候,第二個(gè)元素將會(huì)用作比較-第二行和第三行代碼就發(fā)生了這樣的比較。

當(dāng)元組中的元素都可以被比較時(shí),你也可以使用這些運(yùn)算符來(lái)比較它們的大小。例如,像下面展示的代碼,你可以比較兩個(gè)類型為 (String, Int) 的元組,因?yàn)?IntString 類型的值可以比較。相反,Bool 不能被比較,也意味著存有布爾類型的元組不能被比較。

("blue", -1) < ("purple", 1)       // 正常,比較的結(jié)果為 true
("blue", false) < ("purple", true) // 錯(cuò)誤,因?yàn)?< 不能比較布爾類型

注意

Swift 標(biāo)準(zhǔn)庫(kù)只能比較七個(gè)以內(nèi)元素的元組比較函數(shù)。如果你的元組元素超過(guò)七個(gè)時(shí),你需要自己實(shí)現(xiàn)比較運(yùn)算符。

三元運(yùn)算符(Ternary Conditional Operator)

三元運(yùn)算符的特殊在于它是有三個(gè)操作數(shù)的運(yùn)算符,它的形式是 問(wèn)題 ? 答案 1 : 答案 2。它簡(jiǎn)潔地表達(dá)根據(jù) 問(wèn)題成立與否作出二選一的操作。如果 問(wèn)題 成立,返回 答案 1 的結(jié)果;反之返回 答案 2 的結(jié)果。

三元運(yùn)算符是以下代碼的縮寫(xiě)形式:

if question {
    answer1
} else {
    answer2
}

這里有個(gè)計(jì)算表格行高的例子。如果有表頭,那行高應(yīng)比內(nèi)容高度要高出 50 點(diǎn);如果沒(méi)有表頭,只需高出 20 點(diǎn):

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight 現(xiàn)在是 90

上面的寫(xiě)法比下面的代碼更簡(jiǎn)潔:

let contentHeight = 40
let hasHeader = true
var rowHeight = contentHeight
if hasHeader {
    rowHeight = rowHeight + 50
} else {
    rowHeight = rowHeight + 20
}
// rowHeight 現(xiàn)在是 90

第一段代碼例子使用了三元運(yùn)算,所以一行代碼就能讓我們得到正確答案。這比第二段代碼簡(jiǎn)潔得多,無(wú)需將 rowHeight 定義成變量,因?yàn)樗闹禑o(wú)需在 if 語(yǔ)句中改變。

三元運(yùn)算提供有效率且便捷的方式來(lái)表達(dá)二選一的選擇。需要注意的事,過(guò)度使用三元運(yùn)算符會(huì)使簡(jiǎn)潔的代碼變的難懂。我們應(yīng)避免在一個(gè)組合語(yǔ)句中使用多個(gè)三元運(yùn)算符。

空合運(yùn)算符(Nil Coalescing Operator)

空合運(yùn)算符a ?? b)將對(duì)可選類型 a 進(jìn)行空判斷,如果 a 包含一個(gè)值就進(jìn)行解封,否則就返回一個(gè)默認(rèn)值 b。表達(dá)式 a 必須是 Optional 類型。默認(rèn)值 b 的類型必須要和 a 存儲(chǔ)值的類型保持一致。

空合運(yùn)算符是對(duì)以下代碼的簡(jiǎn)短表達(dá)方法:

a != nil ? a! : b

上述代碼使用了三元運(yùn)算符。當(dāng)可選類型 a 的值不為空時(shí),進(jìn)行強(qiáng)制解封(a!),訪問(wèn) a 中的值;反之返回默認(rèn)值 b。無(wú)疑空合運(yùn)算符(??)提供了一種更為優(yōu)雅的方式去封裝條件判斷和解封兩種行為,顯得簡(jiǎn)潔以及更具可讀性。

注意

如果 a 為非空值(non-nil),那么值 b 將不會(huì)被計(jì)算。這也就是所謂的短路求值

下文例子采用空合運(yùn)算符,實(shí)現(xiàn)了在默認(rèn)顏色名和可選自定義顏色名之間抉擇:

let defaultColorName = "red"
var userDefinedColorName: String?   //默認(rèn)值為 nil

var colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName 的值為空,所以 colorNameToUse 的值為 "red"

userDefinedColorName 變量被定義為一個(gè)可選的 String 類型,默認(rèn)值為 nil。由于 userDefinedColorName 是一個(gè)可選類型,我們可以使用空合運(yùn)算符去判斷其值。在上一個(gè)例子中,通過(guò)空合運(yùn)算符為一個(gè)名為 colorNameToUse 的變量賦予一個(gè)字符串類型初始值。 由于 userDefinedColorName 值為空,因此表達(dá)式 userDefinedColorName ?? defaultColorName 返回 defaultColorName 的值,即 red

如果你分配一個(gè)非空值(non-nil)給 userDefinedColorName,再次執(zhí)行空合運(yùn)算,運(yùn)算結(jié)果為封包在 userDefaultColorName 中的值,而非默認(rèn)值。

userDefinedColorName = "green"
colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName 非空,因此 colorNameToUse 的值為 "green"

區(qū)間運(yùn)算符(Range Operators)

Swift 提供了幾種方便表達(dá)一個(gè)區(qū)間的值的區(qū)間運(yùn)算符。

閉區(qū)間運(yùn)算符

閉區(qū)間運(yùn)算符a...b)定義一個(gè)包含從 ab(包括 ab)的所有值的區(qū)間。a 的值不能超過(guò) b。

閉區(qū)間運(yùn)算符在迭代一個(gè)區(qū)間的所有值時(shí)是非常有用的,如在 for-in 循環(huán)中:

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

關(guān)于 for-in 循環(huán),請(qǐng)看控制流

半開(kāi)區(qū)間運(yùn)算符

半開(kāi)區(qū)間運(yùn)算符a..<b)定義一個(gè)從 ab 但不包括 b 的區(qū)間。 之所以稱為半開(kāi)區(qū)間,是因?yàn)樵搮^(qū)間包含第一個(gè)值而不包括最后的值。

半開(kāi)區(qū)間的實(shí)用性在于當(dāng)你使用一個(gè)從 0 開(kāi)始的列表(如數(shù)組)時(shí),非常方便地從0數(shù)到列表的長(zhǎng)度。

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
    print("第 \(i + 1) 個(gè)人叫 \(names[i])")
}
// 第 1 個(gè)人叫 Anna
// 第 2 個(gè)人叫 Alex
// 第 3 個(gè)人叫 Brian
// 第 4 個(gè)人叫 Jack

數(shù)組有 4 個(gè)元素,但 0..<count 只數(shù)到3(最后一個(gè)元素的下標(biāo)),因?yàn)樗前腴_(kāi)區(qū)間。關(guān)于數(shù)組,請(qǐng)查閱數(shù)組。

單側(cè)區(qū)間

閉區(qū)間操作符有另一個(gè)表達(dá)形式,可以表達(dá)往一側(cè)無(wú)限延伸的區(qū)間 —— 例如,一個(gè)包含了數(shù)組從索引 2 到結(jié)尾的所有值的區(qū)間。在這些情況下,你可以省略掉區(qū)間操作符一側(cè)的值。這種區(qū)間叫做單側(cè)區(qū)間,因?yàn)椴僮鞣挥幸粋?cè)有值。例如:

for name in names[2...] {
    print(name)
}
// Brian
// Jack

for name in names[...2] {
    print(name)
}
// Anna
// Alex
// Brian

半開(kāi)區(qū)間操作符也有單側(cè)表達(dá)形式,附帶上它的最終值。就像你使用區(qū)間去包含一個(gè)值,最終值并不會(huì)落在區(qū)間內(nèi)。例如:

for name in names[..<2] {
    print(name)
}
// Anna
// Alex

單側(cè)區(qū)間不止可以在下標(biāo)里使用,也可以在別的情境下使用。你不能遍歷省略了初始值的單側(cè)區(qū)間,因?yàn)楸闅v的開(kāi)端并不明顯。你可以遍歷一個(gè)省略最終值的單側(cè)區(qū)間;然而,由于這種區(qū)間無(wú)限延伸的特性,請(qǐng)保證你在循環(huán)里有一個(gè)結(jié)束循環(huán)的分支。你也可以查看一個(gè)單側(cè)區(qū)間是否包含某個(gè)特定的值,就像下面展示的那樣。

let range = ...5
range.contains(7)   // false
range.contains(4)   // true
range.contains(-1)  // true

邏輯運(yùn)算符(Logical Operators)

邏輯運(yùn)算符的操作對(duì)象是邏輯布爾值。Swift 支持基于 C 語(yǔ)言的三個(gè)標(biāo)準(zhǔn)邏輯運(yùn)算。

  • 邏輯非(!a
  • 邏輯與(a && b
  • 邏輯或(a || b

邏輯非運(yùn)算符

邏輯非運(yùn)算符!a)對(duì)一個(gè)布爾值取反,使得 truefalse,falsetrue。

它是一個(gè)前置運(yùn)算符,需緊跟在操作數(shù)之前,且不加空格。讀作 非 a ,例子如下:

let allowedEntry = false
if !allowedEntry {
    print("ACCESS DENIED")
}
// 輸出 "ACCESS DENIED"

if !allowedEntry 語(yǔ)句可以讀作「如果非 allowedEntry」,接下一行代碼只有在「非 allowedEntry」為 true,即 allowEntryfalse 時(shí)被執(zhí)行。

在示例代碼中,小心地選擇布爾常量或變量有助于代碼的可讀性,并且避免使用雙重邏輯非運(yùn)算,或混亂的邏輯語(yǔ)句。

邏輯與運(yùn)算符

邏輯與運(yùn)算符a && b)表達(dá)了只有 ab 的值都為 true 時(shí),整個(gè)表達(dá)式的值才會(huì)是 true。

只要任意一個(gè)值為 false,整個(gè)表達(dá)式的值就為 false。事實(shí)上,如果第一個(gè)值為 false,那么是不去計(jì)算第二個(gè)值的,因?yàn)樗呀?jīng)不可能影響整個(gè)表達(dá)式的結(jié)果了。這被稱做短路計(jì)算(short-circuit evaluation)。

以下例子,只有兩個(gè) Bool 值都為 true 的時(shí)候才允許進(jìn)入 if:

let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// 輸出 "ACCESS DENIED"

邏輯或運(yùn)算符

邏輯或運(yùn)算符(a || b)是一個(gè)由兩個(gè)連續(xù)的 | 組成的中置運(yùn)算符。它表示了兩個(gè)邏輯表達(dá)式的其中一個(gè)為 true,整個(gè)表達(dá)式就為 true

同邏輯與運(yùn)算符類似,邏輯或也是「短路計(jì)算」的,當(dāng)左端的表達(dá)式為 true 時(shí),將不計(jì)算右邊的表達(dá)式了,因?yàn)樗豢赡芨淖冋麄€(gè)表達(dá)式的值了。

以下示例代碼中,第一個(gè)布爾值(hasDoorKey)為 false,但第二個(gè)值(knowsOverridePassword)為 true,所以整個(gè)表達(dá)是 true,于是允許進(jìn)入:

let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// 輸出 "Welcome!"

邏輯運(yùn)算符組合計(jì)算

我們可以組合多個(gè)邏輯運(yùn)算符來(lái)表達(dá)一個(gè)復(fù)合邏輯:

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// 輸出 "Welcome!"

這個(gè)例子使用了含多個(gè) &&|| 的復(fù)合邏輯。但無(wú)論怎樣,&&|| 始終只能操作兩個(gè)值。所以這實(shí)際是三個(gè)簡(jiǎn)單邏輯連續(xù)操作的結(jié)果。我們來(lái)解讀一下:

如果我們輸入了正確的密碼并通過(guò)了視網(wǎng)膜掃描,或者我們有一把有效的鑰匙,又或者我們知道緊急情況下重置的密碼,我們就能把門(mén)打開(kāi)進(jìn)入。

前兩種情況,我們都不滿足,所以前兩個(gè)簡(jiǎn)單邏輯的結(jié)果是 false,但是我們是知道緊急情況下重置的密碼的,所以整個(gè)復(fù)雜表達(dá)式的值還是 true。

注意

Swift 邏輯操作符 &&|| 是左結(jié)合的,這意味著擁有多元邏輯操作符的復(fù)合表達(dá)式優(yōu)先計(jì)算最左邊的子表達(dá)式。

使用括號(hào)來(lái)明確優(yōu)先級(jí)

為了一個(gè)復(fù)雜表達(dá)式更容易讀懂,在合適的地方使用括號(hào)來(lái)明確優(yōu)先級(jí)是很有效的,雖然它并非必要的。在上個(gè)關(guān)于門(mén)的權(quán)限的例子中,我們給第一個(gè)部分加個(gè)括號(hào),使它看起來(lái)邏輯更明確:

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// 輸出 "Welcome!"

這括號(hào)使得前兩個(gè)值被看成整個(gè)邏輯表達(dá)中獨(dú)立的一個(gè)部分。雖然有括號(hào)和沒(méi)括號(hào)的輸出結(jié)果是一樣的,但對(duì)于讀代碼的人來(lái)說(shuō)有括號(hào)的代碼更清晰??勺x性比簡(jiǎn)潔性更重要,請(qǐng)?jiān)诳梢宰屇愦a變清晰的地方加個(gè)括號(hào)吧!