Swift 5.1 之类型转换与模式匹配的教程详解

2020-05-29 11:00:27于海丽

枚举 Case 模式还匹配枚举类型的可选项。当可选项 Optional 是枚举类型时, .none 和 .some 能够作为枚举类型的其他 case 出现在同一个 switch 语句中。这种简化的语法允许我们省略可选模式。

enum SomeEnum { case left, right,top,down}
let array : Array<SomeEnum?> = [.left,nil,.right,.top,.down]
//方式一:
array.forEach { (item) in
 switch item {
 case .left?:
  print("左")
 case SomeEnum.right?:
  print("右")
 case .down?:
  print("下")
 case .top?:
  print("上")
 default:
  print("没有值")
 }
}
//方式二:
array.forEach { (item) in
 switch item {
 case .some(let x):
  print("对可选项item进行解包得到:(x)")//!< left,right,top,down
 case .none:
  print("没有值") //nil
 }
}

可选模式

可选模式匹配包含在 Optional<Wrapped> 枚举(这是可选项的实现原理)对应的 case 项: some(Wrapped) 中的值。即匹配可选项有值的情况。

public enum Optional<Wrapped> : ExpressibleByNilLiteral {
 /// The absence of a value.
 /// In code, the absence of a value is typically written using the `nil`
 /// literal rather than the explicit `.none` enumeration case.
 case none
 /// The presence of a value, stored as `Wrapped`.
 case some(Wrapped)
 ......
}

可选模式由标识符模式组成后面紧跟 ? 并出现在与枚举 Case 模式相同的位置。 因为可选模式是 Optional<Wrapped> 枚举的 Case 模式语法糖。所以下面两种写法是等效的:

let someInt : Int? = 42
//方式一:枚举case模式
if case let .some(x) = someInt {
 print(x)
}
if case .some(let x) = someInt {
 print(x)
}
//方式二:可选模式
if case let x? = someInt {
 print(x)
}

使用可选模式迭代包含可选项的数组是很方便的:

enum SomeEnum { case left, right,top,down}
let array : Array<SomeEnum?> = [.left,nil,.right,nil,.top,.down]
for case let item? in array {
 print(item)//!< log:left right top down
}
for case let .some(item) in array {
 print(item)//!< log:left right top down
}
for case .some(let item) in array {
 print(item)//!< log:left right top down
}

表达式模式

表达式模式:表示表达式的值,仅出现在 switch 语句的 case 标签中。

表达式模式的机制:使用Swift标准库中的 ~= 操作符将表达式模式中表达式的值与匹配值(输入值)进行比较,若 ~= 返回 true 则证明匹配成功,否则匹配失败。

~= 运算符默认情况下使用 == 运算符比较两个相同类型的值;也可以通过检查某个值是否在某个范围内来匹配范围值。

let point = (9,14)
switch point {
case (9,14):
 print("表达式模式使用`~=`精准匹配::((point.0),(point.1))")
 fallthrough
case (5..<10,0...20):
 print("表达式模式使用`~=`范围匹配:((point.0),(point.1))")
default:
 print("未匹配")
}