Swift 中的可空类型(Optional)

1,307 阅读2分钟

精要

可空类型是Swift中的独特特性,用来指定某个实例可能没有值。

可空类型有两种状态:

  • 有值并可用。
  • 无值为nil,不可用。

可空类型.png

可用指的是可以访问和操作这个实例。对比OC这门语言,OC的对象实例可以为nil,Swift则不行。

NSString *name = nil; // 完全可以
var name: String = nil // 这会报错
var name_optional: String? = nil // 完全可以,定义了拥有String类型值的Optional类型,它的值是可以为nil的

注意String?,它表示这是一个可空类型。

强制展开

var name:String = "Tome"
if name != nil {
  let current_name = name! // 强制展开name,并把其中的值赋给常量current_name
  print("my name is (current_name)")
}

展开表示获取可空类型实例中的可用值,强制展开使用!,因为强制展开可能获取到nil,这将会不可用,所以需要先判断该实例值是否为nil,如果不判断,直接展开,会比较危险。有一种更优雅的方式来干同样的事情:可空实例绑定。

可空实例绑定

当可空类型的变量值为nil,是不能使用的,即使可用,如果不将它展开也是无法使用的,有一种判断并展开的方式:可空实例绑定

var name: String? = "Tom"
// 可空实例绑定做了如下操作
// 1.判断name是否为nil,如果不为nil,就把name中的值展开值赋给临时常量current_name
// 2.执行代码块中的操作
if let current_name = name {
	print("my name is \(current_name)")
}

if代码块中使用current_name是安全的,因为已经进行了的判断和展开。

隐式展开可空类型

可空类型默认是不会展开的,隐式展开类型则与其相反,这是它们唯一的区别。

var name: String! // 定义一个隐式展开可空类型
name = "Tom"
print(name) // 无需展开,输出值 Tom

Swift会尽可能推断最安全的类型:普通的可空实例,所以定义隐式展开可空类型必须显式声明。

可空链式调用

与可空实例绑定类似,可空链式调用提供来一种对可空实例进行查询以判断其是否包含可用值的机制。两者重要的区别是:可空链式调用允许程序员把多个查询串联为一个可空实例的值。

var name: String? = "tom"

// ?. 为可空链式调用,输出 Optional("TOM")
print(name?.uppercased())

// 可空实例绑定则 展开后再调用 uppercased() 方法
if let current_name = name {
    print(current_name.uppercased())
}

nil 合并运算符 ??

处理可空类型时的一个常见操作时:如果有值,那就获取展开的值,如果为nil,就使用默认的值。

var name: String? = "tom"
var current_name = name ?? "no name" // tom 
print(current_name)
name = nil
current_name = name ?? "no name" // 默认值 no name
print(current_name)