Swift 模式(Patterns)
模式(pattern)代表了單個值或者復合值的結構。例如,元組(1, 2)的結構是逗號分隔的,包含兩個元素的列表。因為模式代表一種值的結構,而不是特定的某個值,你可以把模式和各種同類型的值匹配起來。比如,(x, y)可以匹配元組(1, 2),以及任何含兩個元素的元組。除了將模式與一個值匹配外,你可以從復合值中提取出部分或全部,然后分別把各個部分和一個常量或變量綁定起來。
swift語言中模式有2個基本的分類:一類能成功和任何值的類型相匹配,另一類在運行時(runtime)和某特定值匹配時可能會失敗。
第一類模式用于解構簡單變量,常量和可選綁定中的值。此類模式包括通配符模式(wildcard patterns),標識符模式(identifier patterns),以及任何包含了它們的值綁定模式(value binding patterns)或者元祖模式(tuple patterns)。你可以為這類模式指定一個類型標注(type annotation)從而限制它們只能匹配某種特定類型的值。
第二類模式用于全模式匹配,這種情況下你用來相比較的值在運行時可能還不存在。此類模式包括枚舉用例模式(enumeration case patterns),可選模式(optional patterns),表達式模式(expression patterns)和類型轉換模式(type-casting patterns)。你在switch語句的case標簽中,do語句的catch從句中,或者在if, while, guard和for-in語句的case條件句中使用這類模式。
模式(Patterns) 語法
模式?→?通配符模式?類型標注?可選
模式?→?標識符模式?類型標注on)?可選
模式?→?值綁定模式
模式?→?元組模式?類型標注?可選
模式?→?枚舉用例模式
模式?→?可選模式
模式?→?類型轉換模式
模式?→?表達式模式
通配符模式(Wildcard Pattern)
通配符模式由一個下劃線(_)構成,且匹配并忽略任何值。當你不在乎被匹配的值時可以使用該模式。例如,下面這段代碼在閉區間1...3中循環,每次循環時忽略該區間內的當前值:
for _ in 1...3 {// Do something three times. }通配符模式語法
通配符模式?→?_
標識符模式(Identifier Pattern)
標識符模式匹配任何值,并將匹配的值和一個變量或常量綁定起來。例如,在下面的常量聲明中,someValue是一個標識符模式,匹配了類型是Int的42。
let someValue = 42當匹配成功時,42被綁定(賦值)給常量someValue。
如果一個變量或常量聲明的左邊的模式是一個標識符模式,那么這個標識符模式是一個隱式的值綁定模式(value-binding pattern)。
標識符模式語法
標識符模式?→?標識符
值綁定模式(Value-Binding Pattern)
值綁定模式把匹配到的值綁定給一個變量或常量名。把綁定匹配到的值綁定給常量時,用關鍵字let,綁定給變量時,用關鍵字var。
在值綁定模式中的標識符模式會把新命名的變量或常量與匹配值做綁定。例如,你可以拆開一個元組的元素,然后把每個元素綁定到其相應一個的標識符模式中。
let point = (3, 2) switch point {// Bind x and y to the elements of point. case let (x, y):print("The point is at (\(x), \(y)).") } // prints "The point is at (3, 2).”在上面這個例子中,let將元組模式(x, y)分配到各個標識符模式。正是由于這么做,switch語句中case let (x, y):和case (let x, let y):匹配到的值是一樣的。
值綁定(Value Binding)模式語法
值綁定模式?→?var?模式?|?let?模式
元組模式(Tuple Pattern)
元組模式是逗號分隔的,有零個或多個模式的列表,并被一對圓括號括起來。元組模式匹配相應元組類型的值。
你可以使用類型標注去限制一個元組模式能匹配哪些種元組類型。例如,在常量聲明let (x, y): (Int, Int) = (1, 2)中的元組模式(x, y): (Int, Int)只匹配兩個元素都是Int這種類型的元組。如果僅需要限制一個元組模式中的某幾個元素,只需要直接對這幾個元素提供類型標注即可。例如,在let (x: String, y)中的元組模式可以和任何有兩個元素,且第一個元素類型是String的元組類型匹配。
當元組模式被用在for-in語句或者變量或常量聲明時,它僅可以包含通配符模式,標識符模式,可選模式或者其他包含這些模式的元祖模式。比如下面這段代碼就不正確,因為(x, 0)中的元素0是一個表達式模式:
let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] // This code isn't valid. for (x, 0) in points {/* ... */ }對于只包含一個元素的元組,括號是不起作用的。模式只匹配這個單個元素的類型。舉例來說,下面3條語句是等效的:
let a = 2 // a: Int = 2 let (a) = 2 // a: Int = 2 let (a): Int = 2 // a: Int = 2元組模式語法
元組模式?→?(?元組模式元素列表?可選?)
元組模式元素列表?→?元組模式元素?|?元組模式元素?,?元組模式元素列表
元組模式元素?→?模式
枚舉用例模式(Enumeration Case Pattern)
一個枚舉用例模式匹配現有的某個枚舉類型的某個用例(case)。枚舉用例模式出現在switch語句中的case標簽中,以及if,while,guard和for-in語句的case條件中。
如果你準備匹配的枚舉用例有任何關聯的值,則相應的枚舉用例模式必須指定一個包含每個關聯值元素的元組模式。關于使用switch語句來匹配包含關聯值枚舉用例的例子,請參閱Associated Values.
枚舉用例模式語法
enum-case-pattern?→?類型標識?可選?.?枚舉的case名?元組模式?可選
可選模式(Optional Pattern)
可選模式與封裝在一個Optional(T)或者一個ExplicitlyUnwrappedOptional(T)枚舉中的Some(T)用例相匹配。可選模式由一個標識符模式和緊隨其后的一個問號組成,在某些情況下表現為枚舉用例模式。
由于可選模式是optional和ImplicitlyUnwrappedOptional枚舉用例模式的語法糖(syntactic sugar),下面的2種寫法是一樣的:
let someOptional: Int? = 42 // Match using an enumeration case pattern if case .Some(let x) = someOptional {print(x) }// Match using an optional pattern if case let x? = someOptional {print(x) }如果一個數組的元素是可選類型,可選模式為for-in語句提供了一種在該數組中迭代的簡便方式,只為數組中的非空non-nil元素執行循環體。
let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5] // Match only non-nil values for case let number? in arrayOfOptinalInts {print("Found a \(number)") } //Found a 2 //Found a 3 //Found a 5可選模式語法
可選模式?→?標識符模式??
類型轉換模式(Type-Casting Patterns)
有兩種類型轉換模式,is模式和as模式。這兩種模式只出現在switch語句中的case標簽中。is模式和as模式有以下形式:
is?type
pattern?as?type
is模式僅當一個值的類型在運行時(runtime)和is模式右邊的指定類型一致 - 或者是該類型的子類 - 的情況下,才會匹配這個值。is模式和is操作符有相似表現,它們都進行類型轉換,卻舍棄返回的類型。
as模式僅當一個值的類型在運行時(runtime)和as模式右邊的指定類型一致 - 或者是該類型的子類 - 的情況下,才會匹配這個值。如果匹配成功,被匹配的值的類型被轉換成as模式左邊指定的模式。
關于使用switch語句來匹配is模式和as模式值的例子,請參閱Type Casting for Any and AnyObject。
類型轉換模式語法
type-casting-pattern?→?is模式?|?as模式
is模式?→?is?類型
as模式?→?模式?as?類型
表達式模式(Expression Pattern)
一個表達式模式代表了一個表達式的值。表達式模式只出現在switch語句中的case標簽中。
由表達式模式所代表的表達式與使用了Swift標準庫中~=操作符的輸入表達式的值進行比較。如果~=操作符返回true,則匹配成功。默認情況下,~=操作符使用==操作符來比較兩個相同類型的值。它也可以將一個整型數值與一個Range對象中的一段整數區間做匹配,正如下面這個例子所示:
let point = (1, 2) switch point { case (0, 0):print("(0, 0) is at the origin.") case (-2...2, -2...2):print("(\(point.0), \(point.1)) is near the origin.") default:print("The point is at (\(point.0), \(point.1)).") } // prints "(1, 2) is near the origin.”你可以重載~=操作符來提供自定義的表達式匹配行為。比如你可以重寫上面的例子,拿point表達式去比較字符串形式的點。
// Overload the ~= operator to match a string with an integer func ~=(pattern: String, value: Int) -> Bool {return pattern == "\(value)" } switch point { case ("0", "0"):print("(0, 0) is at the origin.") default:print("The point is at (\(point.0), \(point.1)).") } // prints "(1, 2) is near the origin.”表達式模式語法
表達式模式?→?表達式
總結
以上是生活随笔為你收集整理的Swift 模式(Patterns)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (Android) 如何使用HOOK实现
- 下一篇: java多态的练习 ,定义三个类,父类G