Swift
可选链
本文详细介绍了 Swift 中的可选链,包括其基本概念、替代强制解包、模型类定义、访问属性、调用方法、访问下标以及多层链接。
可选链(Optional Chaining)是一种查询和调用当前可能为 nil 的可选属性、方法及下标的过程。如果可选值有值,则调用成功;如果可选值是 nil,则调用返回 nil。多个调用可以连接在一起形成一个链,如果其中任何一个节点为 nil,整个链就会失败,返回 nil。
替代强制解包
通过在可选值后放置问号 ? 来调用可选链,这与放置感叹号 ! 进行强制解包不同。强制解包在值为 nil 时会触发运行时错误,而可选链只会返回 nil。
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
let john = Person()
// 强制解包会报错,因为 residence 为 nil
// let roomCount = john.residence!.numberOfRooms
// 可选链调用,返回 Int? 类型
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// 打印 "Unable to retrieve the number of rooms."定义模型类
可以使用可选链来调用多层属性、方法和下标。
class Person {
var residence: Residence?
}
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?
}
class Room {
let name: String
init(name: String) { self.name = name }
}
class Address {
var buildingName: String?
var buildingNumber: String?
var street: String?
func buildingIdentifier() -> String? {
if let buildingNumber = buildingNumber, let street = street {
return "\(buildingNumber) \(street)"
} else if buildingName != nil {
return buildingName
} else {
return nil
}
}
}通过可选链访问属性
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.")
}通过可选链调用方法
可以通过可选链调用方法,并检查方法调用是否成功。即使方法没有返回值,可选链也会返回 Void?。
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.")
}通过可选链访问下标
if let firstRoomName = john.residence?[0].name {
print("The first room name is \(firstRoomName).")
} else {
print("Unable to retrieve the first room name.")
}多层链接
可以将多个可选链连接在一起,挖掘模型中更深层的属性、方法和下标。
let john = Person()
john.residence = Residence()
john.residence?.address = Address()
john.residence?.address?.street = "Laurel Street"
if let johnsStreet = john.residence?.address?.street {
print("John's street name is \(johnsStreet).")
} else {
print("Unable to retrieve the address.")
}对返回可选值的函数进行链接
如果函数返回一个可选值,可以在函数调用后加上问号来继续链接。
if let buildingIdentifier = john.residence?.address?.buildingIdentifier() {
print("John's building identifier is \(buildingIdentifier).")
}如果需要进一步访问返回的可选值的属性,问号应放在函数调用的括号后面:
if let beginsWithThe = john.residence?.address?.buildingIdentifier()?.hasPrefix("The") {
if beginsWithThe {
print("John's building identifier begins with \"The\".")
} else {
print("John's building identifier does not begin with \"The\".")
}
}在 GitHub 上编辑
上次更新于