Swift中的可选类型

可选类型

在 swift 中可以使用 可选类型(Optional)来处理值不存在的情况,变量存在值时可以对其进行解析。

比如对数字进行类型转换:

var numberStr = "10"
// value 类型推断为 Int?
// 相当于 var value: Int? = Int(numberStr)
var value = Int(numberStr)

当 numberStr 可以转换时,value 包含 Int 类型的值;当 numberStr 无法转换时,value 不包含值。

Int? 可以被赋值 nil,但是不能用于非可选的变量赋值,如果程序中变量或常量可能包含空值时,需要声明为对应类型的可选类型。

var statusCode: Int? = 400
// 可选类型可以赋值为 nil
statusCode = nil

可以使用 if 和 ! 来处理可选类型:

var number: String = "10"
var value: Int? = Int(number)

if value != nil {
    print("value is \(value!)")
} else {
    print("value is nil")
}

如果确定可选类型变量存在值,则可以使用 ! 解析可选类型的值,注意:使用 ! 解析一个不存在的值会报错。

可选绑定

还可以使用 可选绑定(Optional binding)来判断可选类型是否包含值,如果存在值则将值赋值给一个变量。

var age: Int = 10
var gift: String?
if age <= 10 {
    gift = "糖果🍬"
}

if let myGift = gift {
    print("myGift is \(myGift)")
} else {
    print("myGift is nil")
}

隐式解析可选类型

如果可以确定一个变量一定存在值,则可以将变量声明为隐式解析可选类型,避免每次取值时的判断。

let message1: String? = "message content 1"
// 需要 ! 解析
let messageContent1: String = message1!
print("message content 1: \(messageContent1)")

let message2: String! = "message content 2"
// 不需要 ! 解析
let messageContent2: String = message2
print("message content 2: \(messageContent2)")

但是如果隐式解析可选类型不存在值,也会和使用普通可选类型一样报错。可以把隐式解析可选类型当做一个可以自动解析的可选类型。

⚠️ 如果一个变量之后可能变成 nil 的话请不要使用隐式解析可选类型。如果你需要在变量的生命周期中判断是否是 nil 的话,请使用普通可选类型。

空合运算符

空合运算符 ?? 先对一个可选类型进行判断 result != nil,如果 result 的值不为 nil,则对可选类型 result 进行取值返回 result!,否则返回默认值,默认值与可选类型包含的值必须是同一类型。

let defaultNum = 10
let randomNum: Int?
// 等价于 randomNum != nil ? randomNum! : defaultNum
let result = randomNum ?? defaultNum