对于刚刚接触 Swift 的大家来说, Optionals 这个概念可能会让大家觉得有些陌生。这里就简单的和大家介绍一下 Swift 中的这个概念。
对于使用 Objective-C 进行过开发的朋友来说,nil 这个值并不陌生。任何 Objective-C 中的变量,都可以赋值为 nil,并且对值为 nil 的对象调用方法,不会进行任何实际的操作。
而在 Swift 中,nil 的含义和 Objective-C 中的有所不同。首先,Swift 中无论变量或是常量,都不能被赋予 nil。 它们必须有一个明确的初始值。
如果将 nil 赋值给 Swift 变量,将会产生编译错误:
var str:String = nil
Expression does not conform to type ‘NilLiteralConvertible’
也就是说,在 Swift 中,要使用一个变量必须为它指定一个初始值。这也是 Swift 中的类型安全的一个体现。
前面提到,在 Swift 中,我们对变量不能指定 nil 值,但我们定义变量时,并不一定总要进行初始化。还有,我们的方法返回值,也不一定总是有具体值。这就引出 Swift 中变量定义的一点不方便了。
这样,Swift 又为我们提供了 Optional 类型。我们可以这样理解它:Optional 类型变量的值是可选的(正如 Optional 类型的名称所指示的)。它可以包含具体的值,也可以不包含具体的值(为 nil 的值)。Optional 变量的定义方法如下:
var str:String? = nil
如上面代码所示,我们只需要在变量类型 String 后面添加一个问号 ?
, 就完成了 Optional 类型的定义。我们如果编译上面的代码,就不会产生任何编译错误,代码顺利的被编译通过了。
因为 Optional 类型的变量可以为 nil 值,所以在使用它们的时候就需要进行判断,在 Swift 中,如果直接使用值为 nil 的变量,应用就会崩溃。所以我们要进行必要的判断。
if str != nil {
print(str!)
} else {
print("str is nil")
}
我们注意到,print(str!)
这行代码,str变量的后面多了个叹号。这个叹号的意义我们后面会介绍到,现在暂时将它忽略。
Optional Binding 是 Swift 中提供的一个用于判断 Optional 类型是否为 nil 的机制,它的语法如下:
if let constant = optionalVal {
statements
}
Optional Binding 应用于我们之前定义的 str 变量,就是如下方式:
if let strVal = str {
print(strVal)
}else{
print("str is nil")
}
这次再仔细看看这个输出语句 print(strVal)
, 是不是发现这次没有叹号了。这就引出接下来要说的啦。
在 Swift 中,Optional 并不是一个具体的类型,而是对类型的一个包装。 比如 var str:String?
可以理解为,它并不是一个 String 类型的变量,而是对 String 变量的一个包装。
看看下面的代码,就会更容易理解啦:
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
赋值的常量自动拆包,因此对于这个语法,就不需要显示的使用叹号进行拆包了。
if let strVal = str {
print(strVal)
}else{
print("str is nil")
}
从上面的介绍不难看出,对 Optional 的值进行拆包需要繁琐的使用 ! 语法。这样的操作会很麻烦,尤其是我们已经确认知道某些变量不会是 nil 值的时候。
let strOptional:String? = “An optional string.”
print(strOptional!)
let strImplictlyString:String! = “An implictly optional string.”
print(strImplictlyString)
如上所示,声明 隐式拆包的 Optional 只需要将变量定义结尾的 ? 改成 ! 即可。对于这样声明的变量,在使用它的时候就不再需要加 ! 了。
更多文章请访问我的个人博客 www.theswiftworld.com