Swift Tour Learn (一) -- Swift 語法(語法基礎)

本章將會介紹

什么是Swift
基礎部分(The Basic)

什么是Swift

Swift 是一種新的編程語言,用于編寫 iOS,macOS,watchOS 和 tvOS 的應用程序。Swift 結合了 C 和 Objective-C 的優點并且不受 C 兼容性的限制。Swift 采用安全的編程模式并添加了很多新特性,這將使編程更簡單,更靈活,也更有趣。Swift 是基于成熟而且倍受喜愛的 Cocoa 和 Cocoa Touch 框架,它的降臨將重新定義軟件開發。

Swift 的開發從很久之前就開始了。為了給 Swift 打好基礎,蘋果公司改進了編譯器,調試器和框架結構。我們使用自動引用計數(Automatic Reference Counting, ARC)來簡化內存管理。我們在 Foundation 和 Cocoa 的基礎上構建框架棧使其完全現代化和標準化。 Objective-C 本身支持塊、集合語法和模塊,所以框架可以輕松支持現代編程語言技術。正是得益于這些基礎工作,我們現在才能發布這樣一個用于未來蘋果軟件開發的新語言。

Objective-C 開發者對 Swift 并不會感到陌生。它采用了 Objective-C 的命名參數以及動態對象模型,可以無縫對接到現有的 Cocoa 框架,并且可以兼容 Objective-C 代碼。在此基礎之上,Swift 還有許多新特性并且支持過程式編程和面向對象編程。

Swift 對于初學者來說也很友好。它是第一個既滿足工業標準又像腳本語言一樣充滿表現力和趣味的系統編程語言。它支持代碼預覽(playgrounds),這個革命性的特性可以允許程序員在不編譯和運行應用程序的前提下運行 Swift 代碼并實時查看結果。

Swift 將現代編程語言的精華和蘋果工程師文化的智慧結合了起來。編譯器對性能進行了優化,編程語言對開發進行了優化,兩者互不干擾,魚與熊掌兼得。Swift 既可以用于開發 “hello, world” 這樣的小程序,也可以用于開發一套完整的操作系統。所有的這些特性讓 Swift 對于開發者和蘋果來說都是一項值得的投資。

Swift 是編寫 iOS,macOS,watchOS 和 tvOS 應用的極佳手段,并將伴隨著新的特性和功能持續演進。我們對 Swift 充滿信心,你還在等什么!

基礎部分(The Basic)

Swift 包含了 C 和 Objective-C 上所有基礎數據類型,Int表示整型值; DoubleFloat 表示浮點型值; Bool 是布爾型值;String 是文本型數據。 Swift 還提供了三個基本的集合類型,ArraySetDictionary

就像 C 語言一樣,Swift 使用變量來進行存儲并通過變量名來關聯值。在 Swift 中,廣泛的使用著值不可變的變量,它們就是常量,而且比 C 語言的常量更強大。在 Swift 中,如果你要處理的值不需要改變,那使用常量可以讓你的代碼更加安全并且更清晰地表達你的意圖。

Swift 還增加了 Objective-C 中沒有的高階數據類型比如元組(Tuple)。元組可以讓你創建或者傳遞一組數據,比如作為函數的返回值時,你可以用一個元組可以返回多個值。

Swift 還增加了可選(Optional)類型,用于處理值缺失的情況。可選表示 “那兒有一個值,并且它等于 x ” 或者 “那兒沒有值” 。可選有點像在 Objective-C 中使用 nil ,但是它可以用在任何類型上,不僅僅是類。可選類型比 Objective-C 中的 nil 指針更加安全也更具表現力,它是 Swift 許多強大特性的重要組成部分。

1.常量和變量
  • 常量的值一旦設定就不能改變,而變量的值可以隨意更改。
  • 常量和變量必須在使用前聲明,用 let 來聲明常量,用 var 來聲明變量。
  • 可以在一行中聲明多個常量或者多個變量,用逗號隔開:var x = 0.0, y = 0.0, z = 0.0
2.類型標注(type annotation)

當你聲明常量或者變量的時候可以加上類型標注(type annotation),說明常量或者變量中要存儲的值的類型。

  • 聲明中的冒號代表著“是...類型”,比如var welcomeMessage: String,可以被理解為:“聲明一個類型為 String ,名字為 welcomeMessage 的變量。”

  • 你可以在一行中定義多個同樣類型的變量,用逗號分割,并在最后一個變量名之后添加類型標注:var red, green, blue: Double

注意:
一般來說你很少需要寫類型標注。如果你在聲明常量或者變量的時候賦了一個初始值,Swift可以推斷出這個常量或者變量的類型,請參考類型安全和類型推斷。在上面的例子中,沒有給 welcomeMessage 賦初始值,所以變量 welcomeMessage 的類型是通過一個類型標注指定的,而不是通過初始值推斷的。

3.常量和變量的命名
  • 常量與變量名不能包含數學符號,箭頭,保留的(或者非法的)Unicode 碼位,連線與制表符。也不能以數字開頭,但是可以在常量與變量名的其他地方包含數字。
  • 一旦你將常量或者變量聲明為確定的類型,你就不能使用相同的名字再次進行聲明,或者改變其存儲的值的類型。同時,你也不能將常量與變量進行互轉。
4.輸出常量和變量

你可以用print(_:separator:terminator:)函數來輸出當前常量或變量的值:separatorterminator 參數具有默認值,因此你調用這個函數的時候可以忽略它們。默認情況下,該函數通過添加換行符來結束當前行。如果不想換行,可以傳遞一個空字符串給 terminator 參數--例如,print(someValue, terminator:"")

Swift 用字符串插值(string interpolation)的方式把常量名或者變量名當做占位符加入到長字符串中,Swift 會用當前常量或變量的值替換這些占位符。將常量或變量名放入圓括號中,并在開括號前使用反斜杠將其轉義:

print("The current value of friendlyWelcome is \(friendlyWelcome)")
// 輸出 "The current value of friendlyWelcome is Bonjour!
5.注釋
  • 單行注釋以雙正斜杠(//)作為起始標記
  • 多行注釋 /* code */
  • 可以使用注釋嵌套
6.分號

與其他大部分編程語言不同,Swift 并不強制要求你在每條語句的結尾處使用分號(;),當然,你也可以按照你自己的習慣添加分號。但是如果在同一行內寫多條獨立的語句,那么必須使用分號

7.整數
  • Swift 提供了8,16,32和64位的有符號和無符號整數類型。這些整數類型和 C 語言的命名方式很像,比如8位無符號整數類型是UInt8,32位有符號整數類型是 Int32

  • 可以訪問不同整數類型的 min 和 max 屬性來獲取對應類型的最小值和最大值:

let minValue = UInt8.min  // minValue 為 0,是 UInt8 類型
let maxValue = UInt8.max  // maxValue 為 255,是 UInt8 類型
  • Int整數類型長度與當前平臺的原生字長相同:在32位平臺上,IntInt32 長度相同。在64位平臺上,IntInt64 長度相同。

  • UInt無符號類型 UInt,長度與當前平臺的原生字長相同:在32位平臺上,UIntUInt32 長度相同。在64位平臺上,UIntUInt64 長度相同。

8.浮點數
  • 浮點類型比整數類型表示的范圍更大,可以存儲比 Int 類型更大或者更小的數字。Swift 提供了兩種有符號浮點數類型:

    Double表示64位浮點數。當你需要存儲很大或者很高精度的浮點數時請使用此類型。

    • Float表示32位浮點數。精度要求不高的話可以使用此類型。
  • Double精確度很高,至少有15位數字,而Float只有6位數字。選擇哪個類型取決于你的代碼需要處理的值的范圍,在兩種類型都匹配的情況下,將優先選擇 Double。

9.類型安全(type safe)和類型推斷(type checks)

Swift 是一個類型安全(type safe)的語言。類型安全的語言可以讓你清楚地知道代碼要處理的值的類型。如果你的代碼需要一個String,你絕對不可能不小心傳進去一個Int。由于 Swift 是類型安全的,所以它會在編譯你的代碼時進行類型檢查(type checks),并把不匹配的類型標記為錯誤。這可以讓你在開發的時候盡早發現并修復錯誤。

當你要處理不同類型的值時,類型檢查可以幫你避免錯誤。然而,這并不是說你每次聲明常量和變量的時候都需要顯式指定類型。如果你沒有顯式指定類型,Swift 會使用類型推斷(type inference)來選擇合適的類型。有了類型推斷,編譯器可以在編譯代碼的時候自動推斷出表達式的類型。原理很簡單,只要檢查你賦的值即可。因為有類型推斷,和 C 或者 Objective-C 比起來 Swift 很少需要聲明類型。常量和變量雖然需要明確類型,但是大部分工作并不需要你自己來完成。當你聲明常量或者變量并賦初值的時候類型推斷非常有用。當你在聲明常量或者變量的時候賦給它們一個字面量(literal value 或 literal)即可觸發類型推斷。

如果你沒有給浮點字面量標明類型,Swift 會推斷你想要的是 Double:

let pi = 3.14159
// pi 會被推測為 Double 類型

當推斷浮點數的類型時,Swift 總是會選擇 Double 而不是Float。
如果表達式中同時出現了整數和浮點數,會被推斷為 Double 類型:

let anotherPi = 3 + 0.14159
// anotherPi 會被推測為 Double 類型

原始值 3 沒有顯式聲明類型,而表達式中出現了一個浮點字面量,所以表達式會被推斷為 Double 類型。

10.數值型字面量

整數字面量可以被寫作:

  • 一個十進制數,沒有前綴
  • 一個二進制數,前綴是0b
  • 一個八進制數,前綴是0o
  • 一個十六進制數,前綴是0x

下面的所有整數字面量的十進制值都是17:

let decimalInteger = 17
let binaryInteger = 0b10001       // 二進制的17
let octalInteger = 0o21           // 八進制的17
let hexadecimalInteger = 0x11     // 十六進制的17

數值類字面量可以包括額外的格式來增強可讀性。整數和浮點數都可以添加額外的零并且包含下劃線,并不會影響字面量:

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
11.整數轉化

由于每種整數類型都可以存儲不同范圍的值,所以你必須根據不同情況選擇性使用數值型類型轉換。這種選擇性使用的方式,可以預防隱式轉換的錯誤并讓你的代碼中的類型轉換意圖變得清晰。

要將一種數字類型轉換成另一種,你要用當前值來初始化一個期望類型的新數字,這個數字的類型就是你的目標類型。在下面的例子中,常量twoThousand是UInt16類型,然而常量one是UInt8類型。它們不能直接相加,因為它們類型不同。所以要調用UInt16(one)來創建一個新的UInt16數字并用one的值來初始化,然后使用這個新數字來計算:

let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)

現在兩個數字的類型都是 UInt16,可以進行相加。目標常量 twoThousandAndOne 的類型被推斷為 UInt16,因為它是兩個 UInt16 值的和。

SomeType(ofInitialValue) 是調用 Swift 構造器并傳入一個初始值的默認方法。在語言內部,UInt16 有一個構造器,可以接受一個UInt8類型的值,所以這個構造器可以用現有的 UInt8 來創建一個新的 UInt16。注意,你并不能傳入任意類型的值,只能傳入 UInt16 內部有對應構造器的值。

12.整數和浮點數的轉換

整數和浮點數的轉換必須顯式指定類型:

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi 等于 3.14159,所以被推測為 Double 類型

這個例子中,常量 three 的值被用來創建一個 Double 類型的值,所以加號兩邊的數類型須相同。如果不進行轉換,兩者無法相加。

浮點數到整數的反向轉換同樣行,整數類型可以用 Double 或者 Float 類型來初始化:

let integerPi = Int(pi)
// integerPi 等于 3,所以被推測為 Int 類型

當用這種方式來初始化一個新的整數值時,浮點值會被截斷。也就是說 4.75 會變成 4,-3.9 會變成 -3。

13.類型別名(type aliases)

就是給現有類型定義另一個名字。你可以使用typealias關鍵字來定義類型別名。當你想要給現有類型起一個更有意義的名字時,類型別名非常有用。

typealias AudioSample = UInt16

定義了一個類型別名之后,你可以在任何使用原始名的地方使用別名:

var maxAmplitudeFound = AudioSample.min
// maxAmplitudeFound 現在是 0

本例中,AudioSample被定義為UInt16的一個別名。因為它是別名,AudioSample.min實際上是UInt16.min,所以會給maxAmplitudeFound賦一個初值0。

14.布爾值(Bool)

Swift 有一個基本的布爾(Boolean)類型,叫做Bool。布爾值指邏輯上的值,因為它們只能是真或者假。Swift 有兩個布爾常量,true 和 false

15.元組(tuples)

元組(tuples)把多個值組合成一個復合值。元組內的值可以是任意類型,并不要求是相同類型。

let http404Error = (404, "Not Found")
// http404Error 的類型是 (Int, String),值是 (404, "Not Found")

(404, "Not Found") 元組把一個 Int 值和一個 String 值組合起來表示 HTTP 狀態碼的兩個部分:一個數字和一個人類可讀的描述。這個元組可以被描述為“一個類型為 (Int, String) 的元組”。
你可以把任意順序的類型組合成一個元組,這個元組可以包含所有類型。只要你想,你可以創建一個類型為 (Int, Int, Int) 或者 (String, Bool) 或者其他任何你想要的組合的元組。你可以將一個元組的內容分解(decompose)成單獨的常量和變量,然后你就可以正常使用它們了:

let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// 輸出 "The status code is 404"
print("The status message is \(statusMessage)")
// 輸出 "The status message is Not Found"

如果你只需要一部分元組值,分解的時候可以把要忽略的部分用下劃線(_)標記:

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// 輸出 "The status code is 404"

此外,你還可以通過下標來訪問元組中的單個元素,下標從零開始:

print("The status code is \(http404Error.0)")
// 輸出 "The status code is 404"
print("The status message is \(http404Error.1)")
// 輸出 "The status message is Not Found"

你可以在定義元組的時候給單個元素命名:

let http200Status = (statusCode: 200, description: "OK")

給元組中的元素命名后,你可以通過名字來獲取這些元素的值:

print("The status code is \(http200Status.statusCode)")
// 輸出 "The status code is 200"
print("The status message is \(http200Status.description)")
// 輸出 "The status message is OK"

注意:

元組在臨時組織值的時候很有用,但是并不適合創建復雜的數據結構。如果你的數據結構并不是臨時使用,請使用類或者結構體而不是元組。

16.可選類型(Optionals)

使用可選類型(optionals)來處理值可能缺失的情況。可選類型表示:

  • 有值,等于x
  • 沒有值

注意:
C 和 Objective-C 中并沒有可選類型這個概念。最接近的是 Objective-C 中的一個特性,一個方法要不返回一個對象要不返回nil,nil表示“缺少一個合法的對象”。然而,這只對對象起作用——對于結構體,基本的 C 類型或者枚舉類型不起作用。對于這些類型,Objective-C 方法一般會返回一個特殊值(比如NSNotFound)來暗示值缺失。這種方法假設方法的調用者知道并記得對特殊值進行判斷。然而,Swift 的可選類型可以讓你暗示任意類型的值缺失,并不需要一個特殊值。

Swift 的 Int 類型有一種構造器,作用是將一個 String 值轉換成一個 Int 值。然而,并不是所有的字符串都可以轉換成一個整數。字符串 "123" 可以被轉換成數字 123 ,但是字符串 "hello, world" 不行。
下面的例子使用這種構造器來嘗試將一個 String 轉換成 Int:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推測為類型 "Int?", 或者類型 "optional Int"

因為該構造器可能會失敗,所以它返回一個可選類型(optional)Int,而不是一個 Int。一個可選的 Int 被寫作 Int? 而不是 Int。問號暗示包含的值是可選類型,也就是說可能包含 Int 值也可能不包含值。(不能包含其他任何值比如 Bool 值或者 String 值。只能是 Int 或者什么都沒有。)

17.nil

你可以給可選變量賦值為nil來表示它沒有值:

var serverResponseCode: Int? = 404
// serverResponseCode 包含一個可選的 Int 值 404
serverResponseCode = nil
// serverResponseCode 現在不包含值

注意:
nil不能用于非可選的常量和變量。如果你的代碼中有常量或者變量需要處理值缺失的情況,請把它們聲明成對應的可選類型。

如果你聲明一個可選常量或者變量但是沒有賦值,它們會自動被設置為 nil:

var surveyAnswer: String?
// surveyAnswer 被自動設置為 nil

注意:
Swift 的 nil 和 Objective-C 中的 nil 并不一樣。在 Objective-C 中,nil 是一個指向不存在對象的指針。在 Swift 中,nil 不是指針——它是一個確定的值,用來表示值缺失。任何類型的可選狀態都可以被設置為 nil,不只是對象類型。

18.if語句以及強制解析

你可以使用 if 語句和 nil 比較來判斷一個可選值是否包含值。你可以使用“相等”(==)或“不等”(!=)來執行比較。

如果可選類型有值,它將不等于 nil:

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}
// 輸出 "convertedNumber contains some integer value."
19.可選綁定(optional binding)

使用可選綁定(optional binding)來判斷可選類型是否包含值,如果包含就把值賦給一個臨時常量或者變量。可選綁定可以用在 if 和 while 語句中,這條語句不僅可以用來判斷可選類型中是否有值,同時可以將可選類型中的值賦給一個常量或者變量。

你可以像上面這樣使用可選綁定來重寫 possibleNumber 這個例子:

if let actualNumber = Int(possibleNumber) {
    print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
    print("\'\(possibleNumber)\' could not be converted to an integer")
}
// 輸出 "'123' has an integer value of 123"

這段代碼可以被理解為:“如果 Int(possibleNumber) 返回的可選 Int 包含一個值,創建一個叫做 actualNumber 的新常量并將可選包含的值賦給它。”如果轉換成功,actualNumber 常量可以在 if 語句的第一個分支中使用。它已經被可選類型 包含的 值初始化過,所以不需要再使用 ! 后綴來獲取它的值。在這個例子中,actualNumber 只被用來輸出轉換結果。

你可以在可選綁定中使用常量和變量。如果你想在if語句的第一個分支中操作 actualNumber 的值,你可以改成 if var actualNumber,這樣可選類型包含的值就會被賦給一個變量而非常量。

你可以包含多個可選綁定或多個布爾條件在一個 if 語句中,只要使用逗號分開就行。只要有任意一個可選綁定的值為nil,或者任意一個布爾條件為false,則整個if條件判斷為false,這時你就需要使用嵌套 if 條件語句來處理,如下所示:

if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
}
// 輸出 "4 < 42 < 100"

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
        }
    }
}
// 輸出 "4 < 42 < 100"

注意: 在 if 條件語句中使用常量和變量來創建一個可選綁定,僅在 if 語句的句中(body)中才能獲取到值。相反,在 guard 語句中使用常量和變量來創建一個可選綁定,僅在 guard 語句外且在語句后才能獲取到值,

20.隱式解析可選類型(implicitly unwrapped optionals)

如上所述,可選類型暗示了常量或者變量可以“沒有值”。可選可以通過 if 語句來判斷是否有值,如果有值的話可以通過可選綁定來解析值。

有時候在程序架構中,第一次被賦值之后,可以確定一個可選類型總會有值。在這種情況下,每次都要判斷和解析可選值是非常低效的,因為可以確定它總會有值。這種類型的可選狀態被定義為隱式解析可選類型(implicitly unwrapped optionals)。把想要用作可選的類型的后面的問號(String?)改成感嘆號(String!)來聲明一個隱式解析可選類型。

當可選類型被第一次賦值之后就可以確定之后一直有值的時候,隱式解析可選類型非常有用。隱式解析可選類型主要被用在 Swift 中類的構造過程中。

一個隱式解析可選類型其實就是一個普通的可選類型,但是可以被當做非可選類型來使用,并不需要每次都使用解析來獲取可選值。下面的例子展示了可選類型 String 和隱式解析可選類型 String 之間的區別:

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 需要感嘆號來獲取值

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString  // 不需要感嘆號

你可以把隱式解析可選類型當做一個可以自動解析的可選類型。你要做的只是聲明的時候把感嘆號放到類型的結尾,而不是每次取值的可選名字的結尾。

注意:
如果你在隱式解析可選類型沒有值的時候嘗試取值,會觸發運行時錯誤。和你在沒有值的普通可選類型后面加一個驚嘆號一樣。
你仍然可以把隱式解析可選類型當做普通可選類型來判斷它是否包含值:

if assumedString != nil {
    print(assumedString)
}
// 輸出 "An implicitly unwrapped optional string."

你也可以在可選綁定中使用隱式解析可選類型來檢查并解析它的值:

if let definiteString = assumedString {
    print(definiteString)
}
// 輸出 "An implicitly unwrapped optional string."

注意:
如果一個變量之后可能變成nil的話請不要使用隱式解析可選類型。如果你需要在變量的生命周期中判斷是否是nil的話,請使用普通可選類型。

21.錯誤處理(error handling)

你可以使用 錯誤處理(error handling) 來應對程序執行中可能會遇到的錯誤條件。相對于可選中運用值的存在與缺失來表達函數的成功與失敗,錯誤處理可以推斷失敗的原因,并傳播至程序的其他部分。當一個函數遇到錯誤條件,它能報錯。調用函數的地方能拋出錯誤消息并合理處理。

func canThrowAnError() throws {
    // 這個函數有可能拋出錯誤
}

一個函數可以通過在聲明中添加throws關鍵詞來拋出錯誤消息。當你的函數能拋出錯誤消息時, 你應該在表達式中前置try關鍵詞。

do {
    try canThrowAnError()
    // 沒有錯誤消息拋出
} catch {
    // 有一個錯誤消息拋出
}

一個do語句創建了一個新的包含作用域,使得錯誤能被傳播到一個或多個catch從句。
這里有一個錯誤處理如何用來應對不同錯誤條件的例子。

func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}

在此例中,makeASandwich()(做一個三明治)函數會拋出一個錯誤消息如果沒有干凈的盤子或者某個原料缺失。因為 makeASandwich() 拋出錯誤,函數調用被包裹在 try 表達式中。將函數包裹在一個 do 語句中,任何被拋出的錯誤會被傳播到提供的 catch 從句中。

如果沒有錯誤被拋出,eatASandwich() 函數會被調用。如果一個匹配 SandwichError.outOfCleanDishes 的錯誤被拋出,washDishes() 函數會被調用。如果一個匹配 SandwichError.missingIngredients 的錯誤被拋出,buyGroceries(_:) 函數會被調用,并且使用 catch 所捕捉到的關聯值 [String] 作為參數。

22.斷言(assertion)

可選類型可以讓你判斷值是否存在,你可以在代碼中優雅地處理值缺失的情況。然而,在某些情況下,如果值缺失或者值并不滿足特定的條件,你的代碼可能沒辦法繼續執行。這時,你可以在你的代碼中觸發一個 斷言(assertion) 來結束代碼運行并通過調試來找到值缺失的原因。

可以使用全局 assert(::file:line:) 函數來寫一個斷言。向這個函數傳入一個結果為 true 或者 false 的表達式以及一條信息,當表達式的結果為 false 的時候這條信息會被顯示:

let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// 因為 age < 0,所以斷言會觸發

如果不需要斷言信息,可以省略,就像這樣:

assert(age >= 0)

注意:
當代碼使用優化編譯的時候,斷言將會被禁用,例如在 Xcode 中,使用默認的 target Release 配置選項來 build 時,斷言會被禁用。

當條件可能為假時使用斷言,但是最終一定要保證條件為真,這樣你的代碼才能繼續運行。斷言的適用情景:

  • 整數類型的下標索引被傳入一個自定義下標實現,但是下標索引值可能太小或者太大。
  • 需要給函數傳入一個值,但是非法的值可能導致函數不能正常執行。
  • 一個可選值現在是 nil,但是后面的代碼運行需要一個非 nil 值。

注意:
斷言可能導致你的應用終止運行,所以你應當仔細設計你的代碼來讓非法條件不會出現。然而,在你的應用發布之前,有時候非法條件可能出現,這時使用斷言可以快速發現問題。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容