模式表示单个值或复合值的结构。例如,元组的结构是两个元素的逗号分隔列表。因为模式表示值的结构而不是任何一个特定值,所以可以将它们与各种值匹配。例如,模式匹配元组和任何其他两元素元组。除了将模式与值匹配之外,您还可以提取部分或全部复合值,并将每个部分绑定到常量或变量名称。(1, 2)
(x, y)
(1, 2)
在Swift中,有两种基本类型的模式:成功匹配任何类型值的模式,以及可能无法在运行时匹配指定值的模式。
第一种模式用于在简单变量,常量和可选绑定中对值进行解构。这些包括通配符模式,标识符模式以及包含它们的任何值绑定或元组模式。您可以为这些模式指定类型注释,以将它们约束为仅匹配特定类型的值。
第二种模式用于完整模式匹配,其中您尝试匹配的值可能在运行时不存在。这些包括枚举案例模式,可选模式,表达模式和类型转换模式。你在的情况下,标签使用这些模式switch
声明,一个catch
一个的条款do
声明,或在的情况下条件if
,while
,guard
,或for
- in
语句。
1 GRAMMAR OF A PATTERN 2 3 pattern → wildcard-pattern type-annotation opt 4 5 pattern → identifier-pattern type-annotation opt 6 7 pattern → value-binding-pattern 8 9 pattern → tuple-pattern type-annotation opt 10 11 pattern → enum-case-pattern 12 13 pattern → optional-pattern 14 15 pattern → type-casting-pattern 16 17 pattern → expression-pattern
通配符模式
甲通配符模式相匹配,并且忽略任何值,并且由一个下划线的(_
)。如果不关心要匹配的值,请使用通配符模式。例如,以下代码遍历闭合范围1...3
,忽略循环每次迭代的范围的当前值:
1 for _ in 1...3 { 2 // Do something three times. 3 }
1 GRAMMAR OF A WILDCARD PATTERN 2 3 wildcard-pattern → _
标识符模式
一个标识符模式相匹配的任何值且匹配的值绑定到变量或常数名。例如,在以下常量声明中,someValue
是一个与42
type 的值匹配的标识符模式Int
:
1 let someValue = 42
匹配成功后,将值42
绑定(分配)到常量名称someValue
。
当变量或常量声明的左侧的模式是标识符模式时,标识符模式隐式地是值绑定模式的子模式。
标识符模式的语法
标识符模式→ 标识符
值约束模式
值结合模式结合匹配的值到变量或常数名。将匹配值绑定到常量名称的值绑定模式以let
关键字开头; 绑定到变量名称的那些以var
关键字开头。
值绑定模式中的标识符模式将新的命名变量或常量绑定到其匹配值。例如,您可以分解元组的元素,并将每个元素的值绑定到相应的标识符模式。
1 let point = (3, 2) 2 switch point { 3 // Bind x and y to the elements of point. 4 case let (x, y): 5 print("The point is at (\(x), \(y)).") 6 } 7 // Prints "The point is at (3, 2)."
在上面的示例中,let
分配给元组模式中的每个标识符模式。由于这种行为,案例和匹配相同的值。(x, y)
switch
case let (x, y):
case (let x, let y):
1 GRAMMAR OF A VALUE-BINDING PATTERN 2 3 value-binding-pattern → var pattern | let pattern
元组模式
元组模式是逗号分隔的零个或更多个模式列表中,用括号括起来。元组模式匹配相应元组类型的值。
您可以通过使用类型注释来约束元组模式以匹配某些类型的元组类型。例如,常量声明中的元组模式仅匹配其中两个元素都是类型的元组类型。(x, y): (Int, Int)
let (x, y): (Int, Int) = (1, 2)
Int
当元组模式用作for
- in
语句或变量或常量声明中的模式时,它只能包含通配符模式,标识符模式,可选模式或包含这些模式的其他元组模式。例如,以下代码无效,因为0
元组模式中的元素是表达式模式:(x, 0)
1 let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)] 2 // This code isn‘t valid. 3 for (x, 0) in points { 4 /* ... */ 5 }
包含单个元素的元组模式周围的括号无效。该模式匹配该单个元素类型的值。例如,以下内容是等效的:
1 let a = 2 // a: Int = 2 2 let (a) = 2 // a: Int = 2 3 let (a): Int = 2 // a: Int = 2
1 GRAMMAR OF A TUPLE PATTERN 2 3 tuple-pattern → ( tuple-pattern-element-list opt ) 4 5 tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , tuple-pattern-element-list 6 7 tuple-pattern-element → pattern | identifier : pattern
枚举案例模式
一个枚举的情况下模式相匹配的现有枚举类型的情况。枚举案例模式出现在switch
声明的情况下标签和的情况下,条件if
,while
,guard
,和for
- in
报表。
如果您尝试匹配的枚举大小写具有任何关联值,则相应的枚举大小写模式必须指定一个元组模式,该模式包含每个关联值的一个元素。有关使用switch
语句匹配包含关联值的枚举个案的示例,请参阅关联值。
1 GRAMMAR OF AN ENUMERATION CASE PATTERN 2 3 enum-case-pattern → type-identifier opt . enum-case-name tuple-pattern opt
可选模式
一个可选的模式匹配包裹在一个值some(Wrapped)
的情况下Optional<Wrapped>
枚举。可选模式由标识符模式组成,紧接着是问号,并显示在与枚举案例模式相同的位置。
因为可选模式是Optional
枚举案例模式的语法糖,所以以下是等效的:
1 let someOptional: Int? = 42 2 // Match using an enumeration case pattern. 3 if case .some(let x) = someOptional { 4 print(x) 5 } 6 7 // Match using an optional pattern. 8 if case let x? = someOptional { 9 print(x) 10 }
可选模式提供了一种方便的方法来迭代for
- in
语句中的可选值数组,仅针对非nil
元素执行循环体。
1 let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5] 2 // Match only non-nil values. 3 for case let number? in arrayOfOptionalInts { 4 print("Found a \(number)") 5 } 6 // Found a 2 7 // Found a 3 8 // Found a 5
1 GRAMMAR OF AN OPTIONAL PATTERN 2 3 optional-pattern → identifier-pattern ?
类型铸造模式
有两种类型铸造模式,is
模式和as
模式。该is
模式仅出现在switch
语句案例标签中。在is
和as
模式有如下形式:
1 is type 2 pattern as type
的is
模式的值相匹配,如果在运行时该值的类型是相同的的右手侧指定的类型is
模式或该类型的一个子类。该is
模式的行为类似于is
运算符,因为它们都执行类型转换但丢弃返回的类型。
的as
模式的值相匹配,如果在运行时该值的类型是相同的的右手侧指定的类型as
模式或该类型的一个子类。如果匹配成功,则匹配值的类型将转换为模式右侧指定的as
模式。
对于使用中的示例switch
语句来搭配价值观is
和as
模式,看到所有和AnyObject类型转换。
1 GRAMMAR OF A TYPE CASTING PATTERN 2 3 type-casting-pattern → is-pattern | as-pattern 4 5 is-pattern → is type 6 7 as-pattern → pattern as type
表达模式
表达模式表示表达式的值。表达式模式仅出现在switch
语句案例标签中。
使用Swift标准库~=
运算符将表达式模式表示的表达式与输入表达式的值进行比较。如果~=
操作员返回,则匹配成功true
。默认情况下,~=
运算符使用运算符比较两个相同类型的值==
。它还可以通过检查值是否包含在范围内来匹配具有值范围的值,如以下示例所示。
1 let point = (1, 2) 2 switch point { 3 case (0, 0): 4 print("(0, 0) is at the origin.") 5 case (-2...2, -2...2): 6 print("(\(point.0), \(point.1)) is near the origin.") 7 default: 8 print("The point is at (\(point.0), \(point.1)).") 9 } 10 // Prints "(1, 2) is near the origin."
您可以重载~=
运算符以提供自定义表达式匹配行为。例如,您可以重写上面的示例,将point
表达式与点的字符串表示进行比较。
1 // Overload the ~= operator to match a string with an integer. 2 func ~= (pattern: String, value: Int) -> Bool { 3 return pattern == "\(value)" 4 } 5 switch point { 6 case ("0", "0"): 7 print("(0, 0) is at the origin.") 8 default: 9 print("The point is at (\(point.0), \(point.1)).") 10 } 11 // Prints "The point is at (1, 2)."
1 GRAMMAR OF AN EXPRESSION PATTERN 2 3 expression-pattern → expression
原文地址:https://www.cnblogs.com/strengthen/p/9740670.html