深入讲解Swift中的模式匹配
模式匹配
模式匹配是Swift中非常常见的一种编程模式,使用模式匹配,可以帮助我们写出简明、清晰以及易读的代码,使我们的代码变得简洁而强大。
条件判断中的模式匹配
条件判断是我们使用最普遍的流程控制,在Swift中,只能接受Bool类型的值作为条件体;除了直接判断Bool值之外,我们还能使用使用条件语句进行可选绑定,这在我们开发中是非常常用的方式。
匹配枚举值
在Swift中,创建的枚举类型默认是不可比较的(没有实现Comparable协议),这就意味着我们不能直接使用==操作符来判断两个枚举值是否相等,这种情况下,需要使用模式匹配:
创建一个枚举类型:
enumResult{
casesuccess
casefailure
}
初始化一个枚举值:
letresult=Result.success
使用模式匹配来判断创建的枚举值的值:
ifcase.success=result{
print("Valueofresultissuccess.")
}
可选绑定
创建一个可选值:
letoptionalInt:Int?=1
使用可选绑定的方式进行解包:
ifletval=optionalInt{
print("ThevalueofoptionalIntis(val)")
}
funchandleGuard(){
guardletval=optionalIntelse{
return
}
print("ThevalueofoptionalIntis(val)")
}
handleGuard()
可选绑定的另外一种模式,这也是可选绑定中最基础的模式:
ifcase.some(letval)=optionalInt{
print("ThevalueofoptionalIntis(val)")
}
还可以简化为:
ifcaseletval?=optionalInt{
print("ThevalueofoptionalIntis(val)")
}
循环中的模式匹配
问题来了,iflet模式的可选绑定,只能实现一个可选值的绑定,如果我们需要匹配一个数组里边的可选值怎么办呢?这时候我们就不能使用iflet的形式了,需要使用到ifcaselet的形式
创建一个包含可选值的数组:
letvalues:[Int?]=[1,nil,3,nil,5,nil,7,nil,9,nil]
进行遍历:
forvalinvalues{
print("Valueinvaluesis(String(describing:val))")
}
或者:
varvaluesIterator=values.makeIterator()
whileletval=valuesIterator.next(){
print("Valueinvaluesis(String(describing:val))")
}
我们得到了所有的值与可选值,如果我们需要过滤可选值,我们可以这样做:
forvalinvalues.compactMap({$0}){
print("Valueinvaluesis(val)")
}
这样做,增加了时间复杂度,需要进行两次遍历才能将数据过滤出来。我们可以使用模式匹配的方式来这样做:
forcaseletval?invalues{
print("Valueinvaluesis(val)")
}
或者:
valuesIterator=values.makeIterator()
whileletval=valuesIterator.next(),val!=nil{
print("Valueinvaluesis(String(describing:val))")
}
这样就可以将nil值给过滤了,是不是很简单?还可以使用forcase匹配枚举值数组:
letresults:[Result]=[.success,.failure]
forcase.successinresults{
print("Valuesinresultscontainssuccess.")
break
}
对于复杂的枚举类型:
enumNetResource{
casehttp(resource:String)
caseftp(resource:String)
}
letnets:[NetResource]=[.http(resource:"https://www.baidu.com"),.http(resource:"https://www.apple.cn"),.ftp(resource:ftp://192.0.0.1)]
过滤http的值:
forcase.http(letresource)innets{
print("HTTPresource(resource)")
}
for循环使用where从句
除此之外,我们还可以在for循环后边跟上一个where从句来进行模式匹配:
fornotNilValueinvalueswherenotNilValue!=nil{
print("Notnilvalue:(String(describing:notNilValue!))")
}
查询一个数组里边所有能被3整除的数:
letrangeValues=Array(0...999)
forthreeDivideValueinrangeValueswherethreeDivideValue%3==0{
print("Threedevidevalue:(threeDivideValue)")
}
查询所有含有3的数:
forcontainsThreeinrangeValueswhereString(containsThree).contains("3"){
print("Valuecontainsthree:(containsThree)")
}
Switch中的模式匹配
Switch中的模式匹配也很常用,在Switch中合理地使用模式匹配可以为我们带来很多好处,可以使我们的代码更简洁,同时可以减少代码量和增加开发效率。
区间匹配
letvalue=188
switchvalue{
case0..<50:
print("Thevalueisinrange[0,50)")
case50..<100:
print("Thevalueisinrange[50,100)")
case100..<150:
print("Thevalueisinrange[100,150)")
case150..<200:
print("Thevalueisinrange[150,200)")
case200...:
print("Thevalueisinrange[200,")
default:break
}
//Thevalueisinrange[150,200)
匹配元组类型
创建一个元组类型:
lettuples:(Int,String)=(httpCode:404,status:"NotFound.")
进行匹配:
switchtuples{
case(400...,letstatus):
print("Thehttpcodeis40x,httpstatusis(status)")
default:break
}
创建一个点:
letsomePoint=(1,1)
进行匹配:
switchsomePoint{
case(0,0):
print("(somePoint)isattheorigin")
case(_,0):
print("(somePoint)isonthex-axis")
case(0,_):
print("(somePoint)isonthey-axis")
case(-2...2,-2...2):
print("(somePoint)isinsidethebox")
default:
print("(somePoint)isoutsideofthebox")
}
如上,我们在匹配的时候可以使用下划线_对值进行忽略:
switchtuples{
case(404,_):
print("Thehttpcodeis404notfound.")
default:break
}
在switchcase中使用where从句
在case中使用where从句可以使我们的模式匹配看起来更加精简,使匹配的模式更加紧凑:
letyetAnotherPoint=(1,-1)
switchyetAnotherPoint{
caselet(x,y)wherex==y:
print("((x),(y))isonthelinex==y")
caselet(x,y)wherex==-y:
print("((x),(y))isonthelinex==-y")
caselet(x,y):
print("((x),(y))isjustsomearbitrarypoint")
}
总结
Swift中模式匹配的种类
模式匹配可以说是Swift中非常强大的一种编程模式,使用良好的模式匹配,可以帮助我们写出简介、优雅的代码,Swift中的模式匹配包括以下种类:
- 条件判断:if,guard
- 可选绑定:iflet,guardlet,whilelet...
- 循环体:for,while,repeatwhile
- switch
- docatch
什么时候使用where从句?
我们可以在前文的例子中看到,在很多进行模式匹配的地方还使用了where从句,where从句的作用就相当于在模式匹配的基础上在加上条件限制,使用where从句等价于:
fornotNilValueinvalues{
ifnotNilValue!=nil{
print("Notnilvalue:(String(describing:notNilValue!))")
}
}
可以看出,使用where从句可以使我们的代码更加简洁和易读,什么时候使用where?或者说在哪里可以使用where?Swift文档中并没有对where的详细使用进行介绍,但是在实践中发现,where可以使用在以下地方:
- for循环语句
- switch分支
而对于if,guard与while,我们不能在其后面添加where从句,因为他们本身可以进行多个条件的组合.where从句还有一个用法就是对泛型类型进行类型约束,这在泛型的章节中会有介绍.
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。