【Swift基礎】Swift 4.0學習筆記
The Swift Programming Language 4.0 中文版學習筆記 1
1. 基礎部分
註釋
巢狀註釋:
/* A
/* B */
/
常量和變數
常量和變數名可以使用Unicode字元來命名,但不能包含數學符號,箭頭,保留的(或者非法的)Unicode碼位,連線與製表符。也不能以數字開頭。
常量和變數一旦宣告為確定的型別,即不能改變其儲存的值的型別。同時,常量和變數不能互轉。
數字
除非需要特定長度的整數,一般來說使用Int
就夠了,這樣可以提供程式碼一致性和可複用性。
儘量不要使用UInt
,除非需要儲存一個和當前平臺原生字長相同的無符號整數。否則,最好使用Int
Int
可以提高程式碼的可複用性,避免不同型別數字之間的轉換,並且匹配數字的型別推斷。
Double
型別的精確度高於Float
,選擇哪個型別取決於程式碼需要處理的值的範圍,在兩種型別都匹配的情況下,優先選擇Double
。
型別推斷
數字類字面量可由編譯器推斷型別,而數字類常量和變數必須顯式轉換為其他型別。
類型別名
類型別名typealias
就是給現有型別定義另一個名字。
元組
可以把任何順序的型別組合成一個元組,這個元組可以包含所有型別。
可以將一個元組的內容分解為單獨的常量和變數。如果只需要一部分元組值,分解的時候可以把要忽略的部分用下劃線(_
定義元組的時候,可以給單個元素命名。
let http200Status = (statusCode: 200, description: “OK")
print(“status code: \(http200Status.statusCode), description: \(http200Status.1)”)
let (justTheStatusCode, _) = http200Status
可選型別
可選型別可以暗示任意型別的值缺失,並不需要一個如Objective-C中的NSNotFound
這樣的特殊值來標記非物件型別。
可以給可選變數賦值為nil
來表示它沒有值,nil
不能用於非可選的常量和變數。
Swift的nil
和Objective-C的nil
並不一樣。後者是一個指向不存在物件的指標。在Swift中,nil
不是指標——它是一個確定的值,用來表示值缺失。
可選繫結
使用可選繫結(optional binding)來判斷可選型別是否包含值,如果包含值就把值賦值給一個臨時常量/變數。可選繫結可以用在if
和while
語句中。
注意:在if
條件語句中使用常量/變數來建立一個可選繫結,僅在if
語句的句中(body
)中才能獲取到值。相反,在guard
語句中使用常量/變數來建立一個可選繫結,僅在guard
語句外且在語句後才能獲取到值。
隱式解析可選型別
有時在程式架構中,第一次賦值之後可以確定一個可選型別總會有值。這種情況下,每次都要判斷和解析可選型別是非常低效的。這種型別的可選狀態被定義為隱式解析可選型別(implicitly unwrapped optionals)。把想要用做可選型別的後面的問號(String?
)改為感嘆號(String!
)來宣告一個隱式解析可選型別。
注意:只在確定一個變數不可能變為nil
時才使用隱式解析可選型別。否則在隱式解析可選型別沒有值的時候嘗試取值,會觸發執行時錯誤;正如和沒有值的普通可選型別後面加一個驚歎號一樣。
2. 基本運算
空合運算子(Nil Coalescing Operator)
空合運算子(a ?? b
)將對可選型別a
進行空判斷,如果包含一個值就進行解封,否則就返回一個預設值b
。注意這裡,a
必須是可選型別, 預設值b
的型別必須與a
儲存值的型別保持一致。
區間運算子(Range Operators)
a…b // 閉區間運算子
a..<b // 半開區間運算子
array[2…] // 單側區間1
array[…2] // 單側區間2
3. 字串和字元
多行字串字面量
由一對三個雙引號"""
包裹著文字,可實現跨越多行的字串。注意:從開啟引號當前行之後的第一行開始,到關閉引號當前行之前的一行為止。可以在行尾寫一個反斜槓(\
)作為續行符來實現增強程式碼可讀性且避免換行。
關閉引號當前行之前的空白字串告訴Swift編譯器其他各行多少空白字串需要忽略。
字串是值型別
Swift的String
是值型別。拷貝的方式保證了在函式/方法中傳遞的是字串的值。
連線字串和字元
字串支援的運算子包括+
+=
==
!=
,也可以使用append()
方法將一個字元附加到一個字串變數的尾部。
字串插值
字串插值是構建新字串的方式之一,可以包含常量、變數、字面量和表示式。
4. 集合型別(Collection Types)
Swift語言提供Array
(有序資料集合)、Set
(無序不重複資料集合)、 Dictionary
(無序鍵值對集合)三種基本集合型別用來儲存集合資料。它們儲存的資料型別必須明確。
集合的可變性
如果集合賦值給一個變數,則這個集合是可變的;否則分配給一個常量,則是不可變的。
陣列(Array)
陣列Array
支援使用加法運算子+
和加法賦值運算子+=
。[]
是空陣列。
注意:自定義型別通過實現
Hashable
協議,可以作為集合的值的型別或者是字典的鍵的型別。實現Hashable
協議,需要提供一個型別為Int
的可讀屬性hashValue
。
集合(Set)
你可以高效地完成Set
的一些基本操作,比如把兩個集合組合到一起,判斷兩個集合共有元素,或者判斷兩個集合是否全包含,部分包含或者不相交。
字典(Dictionary)
通過訪問keys
或者values
屬性,我們也可以遍歷字典的鍵或者值。
5. 控制流
Swift提供了多種流程控制結構,包括可以多次執行任務的while/(repeat-while)迴圈,基於特定條件選擇執行不同程式碼分支的if、guard和switch語句,還有控制流程跳轉到其他程式碼位置的break和continue語句。
Swift 還提供了for-in迴圈,用來更簡單地遍歷陣列(Array),字典(Dictionary),區間(Range),字串(String)和其他序列型別。
Swift 的switch語句比 C 語言中更加強大。case 還可以匹配很多不同的模式,包括範圍匹配,元組(tuple)和特定型別匹配。switch語句的 case 中匹配的值可以宣告為臨時常量或變數,在 case 作用域內使用,也可以配合where來描述更復雜的匹配條件。
Switch
區間匹配
case 分支的模式也可以是一個值的區間。
元組
我們可以使用元組在同一個switch語句中測試多個值。元組中的元素可以是值,也可以是區間。另外,使用下劃線(_)來匹配所有可能的值。
值繫結(Value Bindings)
case 分支允許將匹配的值宣告為臨時常量或變數,並且在case分支體內使用 —— 這種行為被稱為值繫結(value binding)。
case 分支的模式可以使用where語句來判斷額外的條件。
複合匹配
當多個條件可以使用同一種方法來處理時,可以將這幾種可能放在同一個case後面,並且用逗號隔開。
控制轉移語句
控制轉移語句改變程式碼的執行順序,通過它可以實現程式碼的跳轉。
Swift有五種控制轉移語句:
- continue
- break
- fallthrough
- return
- throw
在 Swift 裡,switch語句不會從上一個 case 分支跳轉到下一個 case 分支中。
相比之下,C 語言要求你顯式地插入break語句到每個 case 分支的末尾來阻止自動落入到下一個 case 分支中。
如果你確實需要 C 風格的貫穿的特性,你可以在每個需要該特性的 case 分支中使用fallthrough關鍵字。
可以使用標籤(statement label)來標記一個迴圈體或者條件語句,對於一個條件語句,你可以使用break加標籤的方式,來結束這個被標記的語句。對於一個迴圈語句,你可以使用break或者continue加標籤,來結束或者繼續這條被標記語句的執行。
例如,針對迴圈體的標籤:
label name: while condition { statements }
提前退出
像if
語句一樣,guard
的執行取決於一個表示式的布林值。我們可以使用guard
語句來要求條件必須為真時,以執行guard
語句後的程式碼。不同於if
語句,一個guard
語句總是有一個else
從句,如果條件不為真則執行else
從句中的程式碼。
guard let/var condition else {
return // break/continue/throw/fatalError()
}
相比於可以實現同樣功能的if語句,按需使用guard
語句會提升我們程式碼的可讀性。它可以使你的程式碼連貫的被執行而不需要將它包在else
塊中,它可以使你在緊鄰條件判斷的地方,處理違規的情況。
檢測API可用性
if #available(platform name version, ..., *) {
APIs 可用,語句將執行
} else {
APIs 不可用,語句將不執行
}