- 作者: SwiftCafe


浅谈 Swift 中的 Optionals

对于刚刚接触 Swift 的大家来说, Optionals 这个概念可能会让大家觉得有些陌生。这里就简单的和大家介绍一下 Swift 中的这个概念。

关于 nil

对于使用 Objective-C 进行过开发的朋友来说,nil 这个值并不陌生。任何 Objective-C 中的变量,都可以赋值为 nil,并且对值为 nil 的对象调用方法,不会进行任何实际的操作。

而在 Swift 中,nil 的含义和 Objective-C 中的有所不同。首先,Swift 中无论变量或是常量,都不能被赋予 nil。 它们必须有一个明确的初始值。

如果将 nil 赋值给 Swift 变量,将会产生编译错误:

1
var str:String = nil

Expression does not conform to type ‘NilLiteralConvertible’

也就是说,在 Swift 中,要使用一个变量必须为它指定一个初始值。这也是 Swift 中的类型安全的一个体现。

Optional

前面提到,在 Swift 中,我们对变量不能指定 nil 值,但我们定义变量时,并不一定总要进行初始化。还有,我们的方法返回值,也不一定总是有具体值。这就引出 Swift 中变量定义的一点不方便了。

这样,Swift 又为我们提供了 Optional 类型。我们可以这样理解它:Optional 类型变量的值是可选的(正如 Optional 类型的名称所指示的)。它可以包含具体的值,也可以不包含具体的值(为 nil 的值)。Optional 变量的定义方法如下:

1
var str:String? = nil

如上面代码所示,我们只需要在变量类型 String 后面添加一个问号 ?, 就完成了 Optional 类型的定义。我们如果编译上面的代码,就不会产生任何编译错误,代码顺利的被编译通过了。

因为 Optional 类型的变量可以为 nil 值,所以在使用它们的时候就需要进行判断,在 Swift 中,如果直接使用值为 nil 的变量,应用就会崩溃。所以我们要进行必要的判断。

1
2
3
4
5
if str != nil {
print(str!)
} else {
print("str is nil")
}

我们注意到,print(str!) 这行代码,str变量的后面多了个叹号。这个叹号的意义我们后面会介绍到,现在暂时将它忽略。

Optional Binding

Optional Binding 是 Swift 中提供的一个用于判断 Optional 类型是否为 nil 的机制,它的语法如下:

1
2
3
if let constant = optionalVal {
statements
}

Optional Binding 应用于我们之前定义的 str 变量,就是如下方式:

1
2
3
4
5
if let strVal = str {
print(strVal)
}else{
print("str is nil")
}

这次再仔细看看这个输出语句 print(strVal), 是不是发现这次没有叹号了。这就引出接下来要说的啦。

Optional 拆包

在 Swift 中,Optional 并不是一个具体的类型,而是对类型的一个包装。 比如 var str:String? 可以理解为,它并不是一个 String 类型的变量,而是对 String 变量的一个包装。

看看下面的代码,就会更容易理解啦:

1
2
3
4
var strVal:String = “swift string variable”
var strOptional:String? = “swift”string optionals”
print(strVal)
print(strOptional!)

因为 strVal 是一个普通变量,所以我们直接就可以访问到它所包含的值 print(strVal)。而 strOptional 是一个 Optional 包装过的变量,所以要访问它所包含的值,就要对它进行拆包 print(strOptional!)。这样前面我们一直在讨论的叹号的作用就一目了然了吧。

还记得上面提到的 Optional Binding 吗,这个语法规则会将 let 赋值的常量自动拆包,因此对于这个语法,就不需要显示的使用叹号进行拆包了。

1
2
3
4
5
if let strVal = str {
print(strVal)
}else{
print("str is nil")
}

隐式 Optional 拆包

从上面的介绍不难看出,对 Optional 的值进行拆包需要繁琐的使用 ! 语法。这样的操作会很麻烦,尤其是我们已经确认知道某些变量不会是 nil 值的时候。

1
2
3
4
5
let strOptional:String? = “An optional string.”
print(strOptional!)
let strImplictlyString:String! = “An implictly optional string.”
print(strImplictlyString)

如上所示,声明 隐式拆包的 Optional 只需要将变量定义结尾的 ? 改成 ! 即可。对于这样声明的变量,在使用它的时候就不再需要加 ! 了。

如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。




微信公众平台
更多精彩内容,请关注微信公众号


公众号:swift-cafe
邮件订阅
请输入您的邮箱,我们会把最新的内容推送给您: