模式

优质
小牛编辑
125浏览
2023-12-01

模式(pattern)代表了單個值或者複合值的結構。例如,元組(1, 2)的結構是逗號分隔的,包含兩個元素的列表。因為模式代表一種值的結構,而不是特定的某個值,你可以把模式和各種同型別的值匹配起來。比如,(x, y)可以匹配元組(1, 2),以及任何含兩個元素的元組。除了將模式與一個值匹配外,你可以從合成值中提取出部分或全部,然後分別把各個部分和一個常數或變數綁定起來。

在Swift中,模式出現在變數和常數的宣告(在它們的左側),for-in語句和switch語句(在它們的case標簽)中。儘管任何模式都可以出現在switch語句的case標簽中,但在其他情況下,只有通配符模式(wildcard pattern),識別符號模式(identifier pattern)和包含這兩種模式的模式才能出現。

你可以為通配符模式(wildcard pattern),識別符號模式(identifier pattern)和元組模式(tuple pattern)指定型別註解,用來限制這種模式只匹配某種型別的值。

模式(Patterns) 語法
模式通配符模式 型別注解 可選
模式識別符號模式 型別注解on) 可選
模式值綁定模式
模式元組模式 型別注解 可選
模式enum-case-pattern
模式type-casting-pattern
模式表達式模式

通配符模式(Wildcard Pattern)

通配符模式匹配並忽略任何值,包含一個底線(_)。當你不關心被匹配的值時,可以使用此模式。例如,下面這段程式碼進行了1...3的迴圈,並忽略了每次迴圈的值:

for _ in 1...3 {
    // Do something three times.
}

通配符模式語法
通配符模式_

識別符號模式(Identifier Pattern)

識別符號模式匹配任何值,並將匹配的值和一個變數或常數綁定起來。例如,在下面的常數申明中,someValue是一個識別符號模式,匹配了型別是Int42

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):
    println("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 {
    /* ... */
}

對於只包含一個元素的元組,括號是不起作用的。模式匹配那個單個元素的型別。例如,下面是等效的:

let a = 2        // a: Int = 2
let (a) = 2      // a: Int = 2
let (a): Int = 2 // a: Int = 2

元組模式語法
元組模式( 元組模式元素列表 可選 )
元組模式元素列表元組模式元素 | 元組模式元素 , 元組模式元素列表
元組模式元素模式

列舉用例模式(Enumeration Case Pattern)

列舉用例模式匹配現有的列舉型別的某種用例。列舉用例模式僅在switch語句中的case標簽中出現。

如果你準備匹配的列舉用例有任何關聯的值,則相應的列舉用例模式必須指定一個包含每個關聯值元素的元組模式。關於使用switch語句來匹配包含關聯值列舉用例的範例,請參閱Associated Values.

列舉用例模式語法
enum-case-pattern型別標識 可選 . 列舉的case名 元組模式 可選

型別轉換模式(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-patternis模式 | as模式
is模式is 型別
as模式模式 as 型別

表達式模式(Expression Pattern)

表達式模式代表了一個表達式的值。這個模式只出現在switch語句中的case標簽中。

由表達式模式所代表的表達式用Swift標準函式庫中的~=運算子與輸入表達式的值進行比較。如果~=運算子回傳true,則匹配成功。預設情況下,~=運算子使用==運算子來比較兩個相同型別的值。它也可以匹配一個整數值與一個Range物件中的整數範圍,正如下面這個範例所示:

let point = (1, 2)
switch point {
case (0, 0):
    println("(0, 0) is at the origin.")
case (-2...2, -2...2):
    println("(\(point.0), \(point.1)) is near the origin.")
default:
    println("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"):
    println("(0, 0) is at the origin.")
case ("-2...2", "-2...2"):
    println("(\(point.0), \(point.1)) is near the origin.")
default:
    println("The point is at (\(point.0), \(point.1)).")
}
// prints "(1, 2) is near the origin.”

表達式模式語法
表達式模式表達式