在swift的开发过程中,经常看到不同的if用法,如不注意容易产生误会,所以总结一下if的各种不同用法。
传统的if用法
大部分的语言都会有if
语句,有的语言里if
还是表达式,用法基本大同小异,在swift里面同样存在这种用法,也是最常用的用法
if condition {
statements
} else {
statements
}
其中condition是一个布尔表达式
optional Binding用法
在swift中增加了Optional
对象后,经常要对一个Optional
对象进行nil
判断,比如
func test(_ par: String?) {
if par != nil {
let newStr = par!
let len = newStr.count
}
}
由于这样的判断十分常用,所以就有了optional binding
的语法以方便使用
if let newStr = par {
let len = newStr.count
}
optional binding
的条件在if
语句中以let
或var
开头,后面newStr是一个绑定操作,如果par是nil
,则绑定失败,如果par不是nil
,则par的值绑定在newStr上,绑定成功
模式匹配
pattern
是swift里面非常好用的语法,主要应用在switch case
里面,在if
语句里也可以同样使用,在if
语句中以case
开始的条件都属于模式匹配条件,比如判断一个整数x是不是在[6,12)区间内,
//传统用法
if x>=6 && x < 12 {
}
//模式匹配用法
if case 6..<12 = x {
}
复杂一点,如果x是Optional对象,这里可以采用嵌套的模式匹配
//传统用法
if let x = x, x>=6 && x < 12 {
}
//模式匹配用法
if case .some(6..<12) = x {
}
pattern
有很多种,看一下官方文档
GRAMMAR OF A PATTERN
pattern → wildcard-pattern
pattern → identifier-pattern
pattern → value-binding-pattern
pattern → tuple-pattern
pattern → enum-case-pattern
pattern → optional-pattern
pattern → type-casting-pattern
pattern → expression-pattern
这里不详细介绍这些pattern
,更多的应该switch
里面去学习,也就是说switch
里面可以使用的在if里面都可以使用
这里举一些例子
1. type-casting-pattern
var t : Any = 10
if case is Int = t {
print("bingo")
}
if t is Int {
}
上面两种用法结果是一样的,一种是模式匹配,另外一种是常用的is operator
2. tuple-pattern
if case (1..<10, 1..<20) = (7, 8) {
}
在这里(1..<10, 1..<20)是一个pattern
,而不是普通的tuple
,这里会对左右两边的tuple的元素一一进行patteren match
如果把前面换成一个tuple
就会出错里,试试看下面的代码
let pattern = (1..<10, 1..<20)
if case pattern = (7,8) {
}
3. optional-pattern
var t : Any? = 10
// 判断t是不是nil,和判断 t != nil 等效
if case _? = t {
}
//判断t是不是nil,如果有值则绑定到x
if case let x? = t {
}
4. expression-pattern
前面提到的case 6..<12 = x
实际上就是这一种pattern
,实际上这里调用了一个函数,也是一个操作符~=
func ~= (pattern: String, value: Int) -> Bool {
return pattern == "\(value)"
}
if case "123" = 123 {
}
通过重载~=
操作符,我们可以实现很多自定义的模式匹配,结合起来可以有很多有趣的用法
上面通过一些例子介绍了if中的模式匹配用法,在代码中也有常常遇到这种用法,这种用法可以看成是switch case的一种简易写法,这样理解起来就比较容易了
if case expression1 = expression2 {
statements
}
//等价于
switch expression2 {
case expression1:
statements
default:
break
}
#available用法
这是一种特殊的if
用法,用来判断运行环境
if #available(platform name version, ..., *) {
statements to execute if the APIs are available
} else {
fallback statements to execute if the APIs are unavailable
}
这个比较简单,不再介绍
混合使用
上面四种if的使用方法可以混合使用,在一个if
语句中可以有多个condition
,通过,
分开,这些condition
会依序执行
var t : Any? = 10
if case let xs? = t, xs is Int {
print("bingo")
}
这里会首先将t进行optional-pattern
的匹配和绑定,然后判断xs是否是Int
condition
之前常用&&
操作符进行的判断也可以换成使用逗号分割,效果是一样的
最后看一下官方文档对if
和condition list
的描述
GRAMMAR OF AN IF STATEMENT
if-statement → if condition-list code-block else-clause
else-clause → else code-block | else if-statement
condition-list → condition | condition , condition-list
condition → expression | availability-condition | case-condition | optional-binding-condition
case-condition → case pattern initializer
optional-binding-condition → let pattern initializer | var pattern initializer
总结
这里对if
的几种用法做了一些示例和介绍,主要是要能读懂其他人的代码,自己也可以灵活使用if
语句。
这里对condition
的描述都可以应用在while
和guard
语句里, 同样可以灵活的使用。
参考文档
https://docs.swift.org/swift-book/ReferenceManual/Statements.html#grammar_branch-statement
https://docs.swift.org/swift-book/ReferenceManual/Patterns.html