内容简介:模式匹配是 Swift 中非常常见的一种编程模式,使用模式匹配,可以帮助我们写出简明、清晰以及易读的代码,使我们的代码变得简洁而强大。条件判断是我们使用最普遍的流程控制,在 Swift 中,只能接受 Bool 类型的值作为条件体;除了直接判断 Bool 值之外,我们还能使用使用条件语句进行可选绑定,这在我们开发中是非常常用的方式。在 Swift 中,创建的枚举类型默认是不可比较的(没有实现
模式匹配是 Swift 中非常常见的一种编程模式,使用模式匹配,可以帮助我们写出简明、清晰以及易读的代码,使我们的代码变得简洁而强大。
条件判断中的模式匹配
条件判断是我们使用最普遍的流程控制,在 Swift 中,只能接受 Bool 类型的值作为条件体;除了直接判断 Bool 值之外,我们还能使用使用条件语句进行可选绑定,这在我们开发中是非常常用的方式。
匹配枚举值
在 Swift 中,创建的枚举类型默认是不可比较的(没有实现 Comparable
协议),这就意味着我们不能直接使用 ==
操作符来判断两个枚举值是否相等,这种情况下,需要使用模式匹配:
创建一个枚举类型:
enum Result { case success case failure } 复制代码
初始化一个枚举值:
let result = Result.success 复制代码
使用模式匹配来判断创建的枚举值的值:
if case .success = result { print("Value of result is success.") } 复制代码
可选绑定
创建一个可选值:
let optionalInt: Int? = 1 复制代码
使用可选绑定的方式进行解包:
if let val = optionalInt { print("The value of optionalInt is (val)") } func handleGuard() { guard let val = optionalInt else { return } print("The value of optionalInt is (val)") } handleGuard() 复制代码
可选绑定的另外一种模式,这也是可选绑定中最基础的模式:
if case .some(let val) = optionalInt { print("The value of optionalInt is (val)") } 复制代码
还可以简化为:
if case let val? = optionalInt { print("The value of optionalInt is (val)") } 复制代码
循环中的模式匹配
问题来了, if
let
模式的可选绑定,只能实现一个可选值的绑定,如果我们需要匹配一个数组里边的可选值怎么办呢?这时候我们就不能使用 if
let
的形式了,需要使用到 if
case
let
的形式
创建一个包含可选值的数组:
let values: [Int?] = [1, nil, 3, nil, 5, nil, 7, nil, 9, nil] 复制代码
进行遍历:
for val in values { print("Value in values is (String(describing: val))") } 复制代码
或者:
var valuesIterator = values.makeIterator() while let val = valuesIterator.next() { print("Value in values is (String(describing: val))") } 复制代码
我们得到了所有的值与可选值,如果我们需要过滤可选值,我们可以这样做:
for val in values.compactMap({ $0 }) { print("Value in values is (val)") } 复制代码
这样做,增加了时间复杂度,需要进行两次遍历才能将数据过滤出来。我们可以使用模式匹配的方式来这样做:
for case let val? in values { print("Value in values is (val)") } 复制代码
或者:
valuesIterator = values.makeIterator() while let val = valuesIterator.next(), val != nil { print("Value in values is (String(describing: val))") } 复制代码
这样就可以将 nil 值给过滤了,是不是很简单?还可以使用 for
case
匹配枚举值数组:
let results: [Result] = [.success, .failure] for case .success in results { print("Values in results contains success.") break } 复制代码
对于复杂的枚举类型:
enum NetResource { case http(resource: String) case ftp(resource: String) } let nets: [NetResource] = [.http(resource: "https://www.baidu.com"), .http(resource: "https://www.apple.cn"), .ftp(resource: "ftp://192.0.0.1")] 复制代码
过滤 http 的值:
for case .http(let resource) in nets { print("HTTP resource (resource)") } 复制代码
for
循环使用 where
从句
除此之外,我们还可以在 for
循环后边跟上一个 where
从句来进行模式匹配:
for notNilValue in values where notNilValue != nil { print("Not nil value: (String(describing: notNilValue!))") } 复制代码
查询一个数组里边所有能被3整除的数:
let rangeValues = Array(0...999) for threeDivideValue in rangeValues where threeDivideValue % 3 == 0 { print("Three devide value: (threeDivideValue)") } 复制代码
查询所有含有3的数:
for containsThree in rangeValues where String(containsThree).contains("3") { print("Value contains three: (containsThree)") } 复制代码
Switch 中的模式匹配
Switch 中的模式匹配也很常用,在 Switch 中合理地使用模式匹配可以为我们带来很多好处,可以使我们的代码更简洁,同时可以减少代码量和增加开发效率。
区间匹配
let value = 188 switch value { case 0..<50: print("The value is in range [0, 50)") case 50..<100: print("The value is in range [50, 100)") case 100..<150: print("The value is in range [100, 150)") case 150..<200: print("The value is in range [150, 200)") case 200...: print("The value is in range [200, ") default: break } // The value is in range [150, 200) 复制代码
匹配元组类型
创建一个元组类型:
let tuples: (Int, String) = (httpCode: 404, status: "Not Found.") 复制代码
进行匹配:
switch tuples { case (400..., let status): print("The http code is 40x, http status is (status)") default: break } 复制代码
创建一个点:
let somePoint = (1, 1) 复制代码
进行匹配:
switch somePoint { case (0, 0): print("(somePoint) is at the origin") case (_, 0): print("(somePoint) is on the x-axis") case (0, _): print("(somePoint) is on the y-axis") case (-2...2, -2...2): print("(somePoint) is inside the box") default: print("(somePoint) is outside of the box") } 复制代码
如上,我们在匹配的时候可以使用下划线 _
对值进行忽略:
switch tuples { case (404, _): print("The http code is 404 not found.") default: break } 复制代码
在 switch
case
中使用 where
从句
在 case 中使用 where 从句可以使我们的模式匹配看起来更加精简,使匹配的模式更加紧凑:
let yetAnotherPoint = (1, -1) switch yetAnotherPoint { case let (x, y) where x == y: print("((x), (y)) is on the line x == y") case let (x, y) where x == -y: print("((x), (y)) is on the line x == -y") case let (x, y): print("((x), (y)) is just some arbitrary point") } 复制代码
总结
Swift 中模式匹配的种类
模式匹配可以说是 Swift 中非常强大的一种编程模式,使用良好的模式匹配,可以帮助我们写出简介、优雅的代码,Swift 中的模式匹配包括以下种类:
-
条件判断:
if
,guard
-
可选绑定:
if
let
,guard
let
,while
let
... -
循环体:
for
,while
,repeat
while
-
switch
-
do
catch
什么时候使用 where
从句?
我们可以在前文的例子中看到,在很多进行模式匹配的地方还使用了 where
从句, where
从句的作用就相当于在模式匹配的基础上在加上条件限制,使用 where
从句等价于:
for notNilValue in values { if notNilValue != nil { print("Not nil value: (String(describing: notNilValue!))") } } 复制代码
可以看出,使用 where
从句可以使我们的代码更加简洁和易读,什么时候使用 where
? 或者说在哪里可以使用 where
? Swift 文档中并没有对 where
的详细使用进行介绍,但是在实践中发现, where
可以使用在以下地方:
for switch
而对于 if
, guard
与 while
,我们不能在其后面添加 where
从句,因为他们本身可以进行多个条件的组合. where
从句还有一个用法就是对泛型类型进行类型约束,这在泛型的章节中会有介绍.
以上所述就是小编给大家介绍的《Swift中的模式匹配》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Nginx Essentials
Valery Kholodkov / Packt Publishing / 2015-7-1 / USD 34.99
About This Book Learn how to set up, configure, and operate an Nginx installation for day-to-day useExplore the vast features of Nginx to manage it like a pro, and use them successfully to run your......一起来看看 《Nginx Essentials》 这本书的介绍吧!