可选链是一个在**可选值(可能为nil)序列**上进行**查询和调用属性、方法和下标的过程**。如果可选变量包含一个值,属性、方法和下标的调用将会成功,如果可选变量等于 nil,属性、方法和下标的调用将返回 nil 。多个查询可以链接在一起,如果其中一个调用节点失败,整个过程将失败并返回 nil。
Swift 中的可选链与 Objective-C 中的 nil 类似,但是可以为任何类型工作,不仅仅限与对象类型,值类型也可以使用。
可选链 VS 强制解包
可选类型有两种使用方式,即使用 ‘?’ 构造的可选链和使用 '!' 进行强制解包。如果失败可选链(?)会以优雅的方式返回 nil ,如果可选返回 nil 强制解包操作(!)会触发运行时错误。
**通过 **‘?’ 声明可选特性,不用提供默认值,系统为所有的类型提供 nil 默认值
可选链的返回必然是一个可选值,计数调用过程中的属性、方法或是下标返回非可选值,系统会自动将其转换为可选值。
可选链的返回,必然是 nil 或是一个可选值
强制解包的缺点
class Person {
var residence: Residence? //系统默认为 nil
}class Residence {
var numberOfRooms = 1 //必须提供初始值
}
let john = Person()
此时john.residence == nil。
let roomCount = john.residence!.numberOfRooms
// this triggers a runtime error
使用 '!' 强制解包可选变量 residence ,会触发运行时错误。
如果 residence 有非 nil 值,roomCount 被赋值一个简单的值,非可选类型。
可选链优势
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."
无论 john.residence? 是否成功,john.residence?.numberOfRooms 返回的必将是一个可选值类型,即 nil 或是 Int? 。
通过可选链访问属性
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// Prints "Unable to retrieve the number of rooms."
通过可选链调用方法
class Residence {
var rooms = [Room]()
var numberOfRooms: Int {
return rooms.count
}
subscript(i: Int) -> Room {
get {
return rooms[i]
}
set {
rooms[i] = newValue
}
}
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
var address: Address?
}
if john.residence?.printNumberOfRooms() != nil {
print("It was possible to print the number of rooms.")
} else {
print("It was not possible to print the number of rooms.")
}
// Prints "It was not possible to print the number of rooms."
通过可选链访问下标
if let firstRoomName = john.residence?[0].name {
print("The first room name is \(firstRoomName).")
} else {
print("Unable to retrieve the first room name.")
}
// Prints "Unable to retrieve the first room name."
访问可选类型的下标
var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0] += 1
testScores["Brian"]?[0] = 72
// the "Dave" array is now [91, 82, 84] and the "Bev" array is now [80, 94, 81]
多级可选链返回不变性
多级可选链,无论成功与否,都将返回序列上最后的节点对应的可选值。