> 1.0 翻譯:[honghaoz](https://github.com/honghaoz)?校對:[numbbbbb](https://github.com/numbbbbb),?[stanzhai](https://github.com/stanzhai)
>
> 2.0 翻譯+校對:[ray16897188](https://github.com/ray16897188)
本頁內容包括:
[TOC]
模式(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) 語法
> 模式 → _通配符模式_ _類型標注_ 可選
> 模式 → _標識符模式_ _類型標注_ 可選
> 模式 → _值綁定模式_
> 模式 → _元組模式_ _類型標注_ 可選
> 模式 → _枚舉用例模式_
> 模式 → _可選模式_
> 模式 → _類型轉換模式_
> 模式 → _表達式模式_
## 通配符模式(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
- 關于 Swift
- Swift 初見
- Swift 版本歷史記錄
- Swift1.0 發布內容
- Swift 教程
- 基礎部分
- 基本運算符
- 字符串和字符
- 集合類型
- 控制流
- 函數
- 閉包
- 枚舉
- 類和結構體
- 屬性
- 方法
- 下標腳本
- 繼承
- 構造過程
- 析構過程
- 自動引用計數
- 可選鏈
- 錯誤處理
- 類型轉換
- 嵌套類型
- 擴展
- 協議
- 泛型
- 權限控制
- 高級操作符
- 語言參考
- 關于語言參考
- 詞法結構
- 類型
- 表達式
- 語句
- 聲明
- 特性
- 模式
- 泛型參數
- 語法總結
- 蘋果官方Blog官方翻譯
- Access Control 權限控制的黑與白
- 造個類型不是夢-白話Swift類型創建
- WWDC里面的那個“大炮打氣球”
- Swift與C語言指針友好合作
- 引用類型和值類型的恩怨
- 訪問控制和Protected
- 可選類型完美解決占位問題