變量

基本操作員

一個運營商是一個特殊的符號,或者你使用來檢查,更改或合并值的短語。例如,加法運算符(+)添加兩個數(shù)字,如in let i = 1 + 2,邏輯AND運算符(&&)組合兩個布爾值,如in if enteredDoorCode && passedRetinaScan。

Swift支持大多數(shù)標準C運算符,并改進了幾種消除常見編碼錯誤的功能。賦值運算符(=)不會返回值,以防止在等于運算符(==)時錯誤地使用該值。算術(shù)運算符(+,-,*/,%等等)檢測和禁止值溢出,與變得比存儲它們的類型的所允許的值的范圍更大或更小數(shù)目的工作時避免意外的結(jié)果。您可以通過使用雨燕的溢出運營商選擇在價值溢出行為,如在溢出運營商。

Swift還提供了在C中沒有的范圍運算符,比如a..<ba...b,作為表達一系列值的快捷方式。

本章介紹Swift中的常用操作符。高級操作符涵蓋了Swift的高級操作符,并描述了如何定義自己的自定義操作符并為您自定義的類型實現(xiàn)標準操作符。

術(shù)語

運算符是一元,二元或三元運算符:

  • 一元運算符在單個目標上運行(例如-a)。一元前綴運算符緊挨著它們的目標(例如!b)出現(xiàn),而一元后綴運算符出現(xiàn)在它們的目標之后(例如c!)。

  • 二元操作符運行在兩個目標上(如2 + 3),并且是中綴,因為它們出現(xiàn)在兩個目標之間。

  • 三元運營商在三個目標上運營。像C一樣,Swift只有一個三元運算符,即三元條件運算符(a ? b : c)。

操作符影響的值是操作數(shù)。在表達式中1 + 2,+符號是二元運算符,它的兩個操作數(shù)是值12。

賦值運算操作

賦值運算符a = b)初始化或更新的價值a與價值b

  1. let b = 10
  2. var a = 5
  3. a = b
  4. // a is now equal to 10

如果賦值的右側(cè)是一個具有多個值的元組,則其元素可以一次分解為多個常量或變量:

  1. let (x, y) = (1, 2)

  2. // x is equal to 1, and y is equal to 2

  3. print(x) //1

與C和Objective-C中的賦值運算符不同,Swift中的賦值運算符本身不返回值。以下聲明無效:

  1. if x = y {
  2. // This is not valid, because x = y does not return a value.
  3. }

此功能可以防止賦值運算=符(==)在實際意圖等于運算符()時被意外使用。通過使if x = y無效,Swift可以幫助您避免代碼中出現(xiàn)這些類型的錯誤。

算術(shù)運算符

Swift支持所有數(shù)字類型的四個標準算術(shù)運算符

  • 加法(+

  • 減法(-

  • 乘法(*

  • 司(/

  1. 1 + 2 // equals 3
  2. 5 - 3 // equals 2
  3. 2 * 3 // equals 6
  4. 10.0 / 2.5 // equals 4.0

與C和Objective-C中的算術(shù)運算符不同,Swift算術(shù)運算符默認情況下不允許值溢出。你可以通過使用Swift的溢出操作符(比如a &+ b)來選擇賦值溢出行為。請參閱溢出操作符

String連接 操作還支持連接:

  1. "hello, " + "world" // equals "hello, world"

剩余操作員

余運算符a % b)的作品如何的好幾倍b將適合的內(nèi)部a,并返回剩下值(被稱為剩余部分)。

注意

余數(shù)運算符(%)在其他語言中也稱為模運算符。然而,它在Swift中對負數(shù)的行為意味著嚴格地說,它是一個余數(shù)而不是模操作。

以下是剩余操作符的工作方式。為了計算9 % 4,你首先要計算出有多少個4s可以放入里面9

<figure class="figure" style="font-size: 0.8rem;">[圖片上傳失敗...(image-3b7ddc-1531103258569)]

</figure>

你可以放入兩個4s 9,剩下的就是1(以橙色顯示)。

在Swift中,這會寫成:

  1. 9 % 4 // equals 1

為了確定答案a % b,%操作員計算下面的公式并remainder作為其輸出返回:

a=(bx some multiplier)+remainder

里面some multiplier最大的倍數(shù)是 哪里? b``a

插入94這個公式得到:

9=(4x 2)+1

計算余數(shù)為負值時應(yīng)用同樣的方法a

  1. -9 % 4 // equals -1

插入-94代入公式得到:

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

給出一個余數(shù)值-1

b負號的值將忽略 符號b。這意味著a % ba % -b始終給出相同的答案。

一元減法運算符

數(shù)值的符號可以使用前綴-(稱為一元減運算符)來切換:

  1. let three = 3
  2. let minusThree = -three // minusThree equals -3
  3. let plusThree = -minusThree // plusThree equals 3, or "minus minus three"

一元減號運算符(-)直接位于運算值的前面,沒有任何空格。

一元加運算符

一元加運算+)只返回其所操作的價值,沒有任何變化:

  1. let minusSix = -6
  2. let alsoMinusSix = +minusSix // alsoMinusSix equals -6

雖然一元加運算符實際上并沒有做任何事情,但是在使用一元減運算符來表示負數(shù)時,也可以使用它來在代碼中提供正數(shù)的對稱性。

復(fù)合分配算子

和C一樣,Swift提供了復(fù)合賦值操作符,它將assignment(=)與另一個操作結(jié)合在一起。一個例子是附加賦值運算符+=):

  1. var a = 1
  2. a += 2
  3. // a is now equal to 3

這個表達方式a += 2是速記的a = a + 2。實際上,添加和分配組合為一個運算符,可同時執(zhí)行兩個任務(wù)。

注意

復(fù)合賦值運算符不返回值。例如,你不能寫let b = a += 2

有關(guān)Swift標準庫提供的運算符的信息,請參閱運算符聲明。

比較運算符

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

  • 等于(a == b

  • 不等于(a != b

  • 大于(a > b

  • 小于(a < b

  • 大于或等于(a >= b

  • 小于或等于(a <= b

注意

Swift還提供了兩個身份運算符===!==),用于測試兩個對象引用是否都引用同一個對象實例。有關(guān)更多信息,請參閱類和結(jié)構(gòu)

每個比較運算符都會返回一個Bool值來指示該語句是否為真:

  1. 1 == 1 // true because 1 is equal to 1
  2. 2 != 1 // true because 2 is not equal to 1
  3. 2 > 1 // true because 2 is greater than 1
  4. 1 < 2 // true because 1 is less than 2
  5. 1 >= 1 // true because 1 is greater than or equal to 1
  6. 2 <= 1 // false because 2 is not less than or equal to 1

比較運算符通常用于條件語句中,如if語句:

  1. let name = "world"
  2. if name == "world" {
  3. print("hello, world")
  4. } else {
  5. print("I'm sorry \(name), but I don't recognize you")
  6. }
  7. // Prints "hello, world", because name is indeed equal to "world".

有關(guān)該if聲明的更多信息,請參閱控制流程。

你可以比較兩個元組,如果它們具有相同的類型和相同數(shù)量的值。元組從左到右進行比較,一次一個值,直到比較發(fā)現(xiàn)兩個不相等的值。這兩個值進行比較,比較的結(jié)果決定了元組比較的總體結(jié)果。如果所有元素都相等,那么元組本身是相等的。例如:

  1. (1, "zebra") < (2, "apple") // true because 1 is less than 2; "zebra" and "apple" are not compared
  2. (3, "apple") < (3, "bird") // true because 3 is equal to 3, and "apple" is less than "bird"
  3. (4, "dog") == (4, "dog") // true because 4 is equal to 4, and "dog" is equal to "dog"

在上面的示例中,您可以在第一行看到從左到右的比較行為。因為1小于2,(1, "zebra")被認為小于(2, "apple"),不管元組中的任何其他值如何。沒關(guān)系,"zebra"不小于"apple",因為比較已經(jīng)由元組的第一個元素決定了。然而,當元組的第一個元素是相同的,他們的第二個元素進行比較 - 這是發(fā)生在第二和第三行。

只有當操作符可以應(yīng)用于各個元組中的每個值時,元組才可以與給定的操作符進行比較。例如,這表現(xiàn)在下面的代碼,就可以比較類型的兩個元組(String, Int),因為這兩個StringInt值可以使用進行比較<運算符。相比之下,兩個元組類型(String, Bool)不能與<運算符進行比較,因為<運算符不能應(yīng)用于Bool值。

  1. ("blue", -1) < ("purple", 1) // OK, evaluates to true
  2. ("blue", false) < ("purple", true) // Error because < can't compare Boolean values

注意

Swift標準庫包含元組少于7個元組的元組比較運算符。要比較具有七個或更多元素的元組,您必須自己實現(xiàn)比較運算符。

三元條件運算符

所述三元條件算子是由三個部分組成,這需要形式的特殊操作question ? answer1 : answer2。這是根據(jù)是否question為真來評估兩個表達式之一的捷徑。如果question屬實,則評估answer1并返回其值; 否則,它會評估answer2并返回其值。

三元條件運算符是下面代碼的簡寫:

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

以下是一個計算表格行高度的示例。如果該行有標題,則行高應(yīng)比內(nèi)容高度高50個點;如果該行沒有標題,則行高應(yīng)高20個點:

  1. let contentHeight = 40
  2. let hasHeader = true
  3. let rowHeight = contentHeight + (hasHeader ? 50 : 20)
  4. // rowHeight is equal to 90

上面的例子是下面代碼的簡寫:

  1. let contentHeight = 40
  2. let hasHeader = true
  3. let rowHeight: Int
  4. if hasHeader {
  5. rowHeight = contentHeight + 50
  6. } else {
  7. rowHeight = contentHeight + 20
  8. }
  9. // rowHeight is equal to 90

第一個例子使用三元條件運算符意味著rowHeight可以在單行代碼上設(shè)置正確的值,這比第二個例子中使用的代碼更簡潔。

三元條件運算符為決定要考慮哪兩個表達式提供了有效的速記。但是,請謹慎使用三元條件運算符。如果過度使用,它的簡潔會導(dǎo)致難以閱讀的代碼。避免將三元條件運算符的多個實例組合成一個復(fù)合語句。

無合并操作員

零-合并運算符a ?? b)進行解包的可選a,如果它包含一個值,或者返回一個默認值b,如果anil。表達式a總是可選的類型。表達式b必須與存儲在里面的類型匹配a。

nil-coalescing運算符是下面代碼的簡寫:

  1. a != nil ? a! : b

上面的代碼使用三元條件操作和強制解包(a!)來訪問內(nèi)部包裹的值aa是不nil,并返回b,否則。nil-coalescing運算符提供了一種更簡潔的方式來以簡明易懂的形式封裝這個條件檢查和解包。

注意

如果值為anil值,b則不評估值。這就是所謂的短路評估。

下面的示例使用nil-coalescing運算符在默認顏色名稱和可選的用戶定義顏色名稱之間進行選擇:

  1. let defaultColorName = "red"

  2. var userDefinedColorName: String? // defaults to nil

  3. var colorNameToUse = userDefinedColorName ?? defaultColorName

  4. // userDefinedColorName is nil, so colorNameToUse is set to the default of "red"

userDefinedColorName變量被定義為可選的String,默認值為nil。由于userDefinedColorName是可選類型,因此您可以使用nil-coalescing運算符來考慮其值。在上面的示例中,運算符用于確定String調(diào)用變量的初始值colorNameToUse。因為userDefinedColorNamenil,表達式userDefinedColorName ?? defaultColorName返回值defaultColorName"red"。

如果您將一個非nil值賦予userDefinedColorName并再次執(zhí)行nil-coalescing操作符檢查,則將userDefinedColorName使用內(nèi)部包裝的值而不是缺省值:

  1. userDefinedColorName = "green"
  2. colorNameToUse = userDefinedColorName ?? defaultColorName
  3. // userDefinedColorName is not nil, so colorNameToUse is set to "green"

范圍運算符

Swift包含幾個范圍運算符,它們是表示一系列值的捷徑。

關(guān)閉范圍操作員

封閉范圍操作符a...b)限定了從運行范圍ab,并且包括這些值ab。值a不得大于b

在遍歷希望使用所有值的范圍(例如使用for- in循環(huán))時,閉范圍運算符很有用:

  1. for index in 1...5 {
  2. print("\(index) times 5 is \(index * 5)")
  3. }
  4. // 1 times 5 is 5
  5. // 2 times 5 is 10
  6. // 3 times 5 is 15
  7. // 4 times 5 is 20
  8. // 5 times 5 is 25

有關(guān)for- in循環(huán)的更多信息,請參閱控制流程。

半開放范圍運算符

所述半開區(qū)間運算符a..<b)限定了從運行范圍ab,但不包括b。據(jù)說它是半開放的,因為它包含了它的第一個值,但不包含它的最終值。與封閉范圍操作符一樣,值a不得大于b。如果值a等于b,則結(jié)果范圍將為空。

當您使用基于零的列表(例如數(shù)組)時,半開范圍特別有用,可以計算(但不包括)列表長度:

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

請注意,該數(shù)組包含四個項目,但0..<count只計算3(數(shù)組中最后一項的索引),因為它是半開范圍。有關(guān)數(shù)組的更多信息,請參閱數(shù)組。

單面范圍

閉范圍運算符有一種替代形式,用于在一個方向上盡可能延續(xù)的范圍 - 例如,范圍包括從索引2到數(shù)組末尾的所有數(shù)組元素。在這些情況下,可以省略范圍運算符一側(cè)的值。這種范圍被稱為單邊范圍,因為操作員只有一方的價值。例如:

  1. for name in names[2...] {

  2. print(name)

  3. }

  4. // Brian

  5. // Jack

  6. for name in names[...2] {

  7. print(name)

  8. }

  9. // Anna

  10. // Alex

  11. // Brian

半開范圍的操作符也具有只寫入其最終值的單面形式。就像在雙方包含一個值時一樣,最終的值不是該范圍的一部分。例如:

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

片面范圍可以用在其他情況下,而不僅僅用于下標。您不能迭代忽略第一個值的單側(cè)范圍,因為尚不清楚應(yīng)在哪里開始迭代。您可以遍歷一個忽略其最終值的單側(cè)范圍; 但是,由于范圍無限期地繼續(xù),因此請確保為循環(huán)添加明確的結(jié)束條件。您還可以檢查單側(cè)范圍是否包含特定值,如下面的代碼所示。

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

邏輯運算符

邏輯運算符修改或組合布爾邏輯值truefalse。Swift支持基于C語言中的三種標準邏輯運算符:

  • 邏輯NOT(!a

  • 邏輯與(a && b

  • 邏輯或(a || b

邏輯NOT運算符

邏輯非運算符!a)反轉(zhuǎn)一個布爾值,使得true成為false,和falsetrue。

邏輯NOT運算符是前綴運算符,并且在其運行的值之前立即出現(xiàn),沒有任何空格。它可以被解讀為“不a”,如下例所示:

  1. let allowedEntry = false
  2. if !allowedEntry {
  3. print("ACCESS DENIED")
  4. }
  5. // Prints "ACCESS DENIED"

該短語if !allowedEntry可以被理解為“如果不允許進入”。后續(xù)行僅在“不允許進入”為真時才被執(zhí)行; 那就是,如果allowedEntryfalse。

正如在這個例子中,仔細選擇布爾常量和變量名稱可以幫助保持代碼的可讀性和簡潔性,同時避免雙重否定或混淆邏輯語句。

邏輯AND運算符

邏輯AND運算符a && b)創(chuàng)建邏輯表達式,其中這兩個值必須true為整體表達也有true

如果任何一個值都是false,則整體表達式也將是false。事實上,如果第一個值是false第二個值,那么甚至不會評估第二個值,因為它不可能使整體表達式等于true。這就是所謂的短路評估

這個例子考慮兩個Bool值,并且只允許訪問如果價值觀true

  1. let enteredDoorCode = true
  2. let passedRetinaScan = false
  3. if enteredDoorCode && passedRetinaScan {
  4. print("Welcome!")
  5. } else {
  6. print("ACCESS DENIED")
  7. }
  8. // Prints "ACCESS DENIED"

邏輯OR運算符

邏輯OR運算符a || b)是來自兩個相鄰管字符制成中綴運算符。您可以使用它來創(chuàng)建邏輯表達式,其中只有一個值必須true用于整體表達式true。

像上面的邏輯與運算符一樣,邏輯或運算符使用短路評估來考慮其表達式。如果邏輯或表達式的左側(cè)是true,右側(cè)不計算,因為它不能改變整個表達式的結(jié)果。

在下面的例子中,第一個Bool值(hasDoorKey)是false,但第二個值(knowsOverridePassword)是true。因為有一個值true,整體表達式也可以評估true,并且允許訪問:

  1. let hasDoorKey = false
  2. let knowsOverridePassword = true
  3. if hasDoorKey || knowsOverridePassword {
  4. print("Welcome!")
  5. } else {
  6. print("ACCESS DENIED")
  7. }
  8. // Prints "Welcome!"

邏輯運算符的組合

您可以組合多個邏輯運算符來創(chuàng)建更長的復(fù)合表達式:

  1. if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
  2. print("Welcome!")
  3. } else {
  4. print("ACCESS DENIED")
  5. }
  6. // Prints "Welcome!"

此示例使用多個&&||運算符來創(chuàng)建較長的復(fù)合表達式。然而,&&||運算符仍然只能運行兩個值,所以這實際上是三個較小的表達式鏈接在一起。該示例可以解讀為:

如果我們輸入了正確的門碼并通過了視網(wǎng)膜掃描,或者如果我們有一個有效的門鑰匙,或者我們知道緊急改寫密碼,則允許進入。

基于,和的值enteredDoorCode,前兩個子表達式是。但是,緊急重寫密碼是已知的,因此整體復(fù)合表達式仍然會評估為。 passedRetinaScan``hasDoorKey``false``true

注意

迅捷邏輯運算符&&||是左結(jié)合,這意味著與多個邏輯運算符復(fù)合表達式首先評估最左邊的子表達式。

顯式括號

在不嚴格需要的情況下包含括號有時很有用,可以使復(fù)雜表達式的意圖更容易閱讀。在上面的門訪問示例中,在復(fù)合表達式的第一部分周圍添加圓括號以使其意圖明確是有用的:

  1. if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
  2. print("Welcome!")
  3. } else {
  4. print("ACCESS DENIED")
  5. }
  6. // Prints "Welcome!"

括號清楚地表明前兩個值在總體邏輯中被認為是單獨的可能狀態(tài)的一部分。復(fù)合表達式的輸出不變,但整體意圖對讀者更清楚??勺x性始終優(yōu)于簡潔性; 在他們幫助明確你的意圖的地方使用括號。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,533評論 0 13
  • 關(guān)于 Swift 重要這個文檔所包含的準備信息, 是關(guān)于開發(fā)的 API 和技術(shù)的。這個信息可能會改變, 根據(jù)這個文...
    無灃閱讀 4,606評論 1 27
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,123評論 2 9
  • 偶聽朋友提到其母和其弟的事情,覺著逗樂,遂記之。 其弟在小學的時候就已頗高頗壯。某日犯錯,其母抬手欲訓(xùn)之。其弟公主...
    陰陰閱讀 364評論 0 0
  • 剛開始接觸小王子的時候,聽名字也知道是童話,童話都不是真實的。用一句歌詞來說,“童話里都是騙人的”,于是了囫圇...
    笑呵呵的何閱讀 522評論 0 0

友情鏈接更多精彩內(nèi)容