Swift - 基本運(yùn)算符

基本運(yùn)算符


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

Swift 所支持運(yùn)算符你可能在別的語(yǔ)言比如 C 語(yǔ)言里已經(jīng)認(rèn)識(shí)了伐厌,同時(shí)為了減少常見(jiàn)編碼錯(cuò)誤對(duì)它們做了部分改進(jìn)旗国。如:賦值符(=)不再有返回值定嗓,這樣就消除了手誤將判等運(yùn)算符(==)寫成賦值符導(dǎo)致代碼錯(cuò)誤的缺陷蜕琴。算術(shù)運(yùn)算符(+-宵溅,*凌简,/% 等)的結(jié)果會(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 的賦值操作并不返回任何值档押。所以下面語(yǔ)句是無(wú)效的:

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

通過(guò)將 if x = y 標(biāo)記為無(wú)效語(yǔ)句,Swift 能幫你避免把 (==)錯(cuò)寫成(=)這類錯(cuò)誤的出現(xiàn)汇荐。

算術(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é)果拦惋,「求余」比「取拇艺悖」更合適些。

我們來(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    // 等于``````

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

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


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

 把 `9` 和 `4` 代入等式中,我們得 `1`:

9 = (4 × 2) +``````

同樣的方法抄沮,我們來(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)符(-)寫在操作數(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)寫,一個(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)

Swift 支持以下的比較運(yùn)算符:

  • 等于(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) 章節(jié)的 Identity Operators 部分。

每個(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)算符是以下代碼的縮寫形式:

 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

上面的寫法比下面的代碼更簡(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)算為二選一場(chǎng)景提供了一個(gè)非常便捷的表達(dá)形式摩瞎。不過(guò)需要注意的是,濫用三元運(yùn)算符會(huì)降低代碼可讀性孝常。所以我們應(yīng)避免在一個(gè)復(fù)合語(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é)果為封包在 userDefinedColorName 中的值,而非默認(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)看 控制流忘分。

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

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

半開區(qū)間的實(shí)用性在于當(dāng)你使用一個(gè)從 0 開始的列表(如數(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)樗前腴_區(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

半開區(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的開端并不明顯侠草。你可以遍歷一個(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)膜掃描,或者我們有一把有效的鑰匙卵洗,又或者我們知道緊急情況下重置的密碼请唱,我們就能把門打開進(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)于門的權(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)的代碼更清晰玻可讀性比簡(jiǎn)潔性更重要信不,請(qǐng)?jiān)诳梢宰屇愦a變清晰的地方加個(gè)括號(hào)吧!


繼續(xù)閱讀 Swift - 字符串和字符

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載亡呵,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者抽活。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锰什,隨后出現(xiàn)的幾起案子下硕,更是在濱河造成了極大的恐慌丁逝,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梭姓,死亡現(xiàn)場(chǎng)離奇詭異霜幼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)誉尖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門罪既,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人铡恕,你說(shuō)我怎么就攤上這事琢感。” “怎么了探熔?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵猩谊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我祭刚,道長(zhǎng),這世上最難降的妖魔是什么墙牌? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任涡驮,我火速辦了婚禮,結(jié)果婚禮上喜滨,老公的妹妹穿的比我還像新娘捉捅。我一直安慰自己,他們只是感情好虽风,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布棒口。 她就那樣靜靜地躺著,像睡著了一般辜膝。 火紅的嫁衣襯著肌膚如雪无牵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天厂抖,我揣著相機(jī)與錄音茎毁,去河邊找鬼。 笑死忱辅,一個(gè)胖子當(dāng)著我的面吹牛七蜘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播墙懂,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼橡卤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了损搬?” 一聲冷哼從身側(cè)響起碧库,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤柜与,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后谈为,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旅挤,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年伞鲫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粘茄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秕脓,死狀恐怖柒瓣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤贩毕,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布棒搜,位于F島的核電站,受9級(jí)特大地震影響磺平,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拐辽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一拣挪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧俱诸,春花似錦菠劝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至园骆,卻和暖如春舔痪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背锌唾。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工辙喂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸠珠。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓巍耗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親渐排。 傳聞我的和親對(duì)象是個(gè)殘疾皇子炬太,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 運(yùn)算符是檢查、改變驯耻、合并值的特殊符號(hào)或短語(yǔ)亲族。例如炒考,加號(hào)+將兩個(gè)數(shù)相加(如let i = 1 + 2)。更復(fù)雜的運(yùn)算...
    窮人家的孩紙閱讀 14,963評(píng)論 3 6
  • Swift中文文檔 運(yùn)算符分為一元霎迫、二元和三元運(yùn)算符 一斋枢、賦值運(yùn)算符 賦值運(yùn)算符: = 例如: (a = b), ...
    伯wen閱讀 671評(píng)論 0 0
  • 術(shù)語(yǔ) 運(yùn)算符分為一元瓤帚、二元和三元運(yùn)算符: 一元運(yùn)算符對(duì)單一操作對(duì)象操作(如 -a)。一元運(yùn)算符分前置運(yùn)算符和后置運(yùn)...
    CoderLGL閱讀 642評(píng)論 0 1
  • Swift 的運(yùn)算符和C以及OC的運(yùn)算符相比并沒(méi)有太大的變化涩赢,但是有很好的補(bǔ)充戈次。 賦值運(yùn)算符(因?yàn)樵M的使用更加豐...
    雪_晟閱讀 687評(píng)論 0 0
  • 術(shù)語(yǔ) 運(yùn)算符分為一元,二元筒扒,三元運(yùn)算符 一元運(yùn)算符對(duì)單一操作對(duì)象進(jìn)行操作(如-a)怯邪,一元運(yùn)算符又分前置前置運(yùn)算符和...
    edison0428閱讀 504評(píng)論 0 0