可选项响应链(学习笔记)
环境Xcode 11.0 beta4 swift 5.1
- 可选项响应链
- 可选项作为强制解包一种替代方案
示例
class Person { var residence: Residence? } // class Residence { var numberOfRooms = 1 } let john = Person() let roomCount = john.residence!.numberOfRooms // this triggers a runtime error 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." // 如果你给residence赋值,结果如下 john.residence = Residence() if let roomCount = john.residence?.numberOfRooms { print("John's residence has \(roomCount) room(s).") } else { print("Unable to retrieve the number of rooms.") } // Prints "John's residence has 1 room(s)."
- 为可选项响应链定义模型类
- 示例代码块
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.") } // Prints "Unable to retrieve the number of rooms." // 通过响应链设置值 // 由于此之前并没有为residence设值,为nil,因此用someAddress赋值不会成功 let someAddress = Address() someAddress.buildingNumber = "29" someAddress.street = "Acacia Road" john.residence?.address = someAddress // 上面的情况不好观察,下面用函数会比较好观察 func createAddress() -> Address { print("Function was called.") // let someAddress = Address() someAddress.buildingNumber = "29" someAddress.street = "Acacia Road" // return someAddress } john.residence?.address = createAddress() // 可以发现上面的 "Function was called."不会打印
- 通过可选项调用方法
- 示例代码块
// 本例中方法 printNumberOfRooms() 有一个隐式返回值 `Void` (或者 `()` 即空元组) // 如果是可选的值调用,则返回的是 `Void?`,不是 `Void` // 因此可以用 `if` 语句来判断方法是否调用成功 // 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." // // 如果属性返回是 `Void?`,也可用同样的判断方法 if (john.residence?.address = someAddress) != nil { print("It was possible to set the address.") } else { print("It was not possible to set the address.") } // Prints "It was not possible to set the address."
- 通过可选项访问下标
?
放在[]
之前,总是紧跟表达式之后
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." // `?` 的执行是在紧跟 residence 之后, 在 `[]` 调用之前 john.residence?[0] = Room(name: "Bathroom") // 上面的尝试赋值也会失败,因为 residence 仍然是 nil
let johnsHouse = Residence() johnsHouse.rooms.append(Room(name: "Living Room")) johnsHouse.rooms.append(Room(name: "Kitchen")) john.residence = johnsHouse // if let firstRoomName = john.residence?[0].name { print("The first room name is \(firstRoomName).") } else { print("Unable to retrieve the first room name.") } // Prints "The first room name is Living Room."
- 可选类型的下标访问,
?
要写在[]
之后
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]
- 连接多层级的响应链
if let johnsstreet = john.residence?.address?.street { print("John's street name is \(johnsstreet).") } else { print("Unable to retrieve the address.") } // Prints "Unable to retrieve the address." // 如果你给 address 赋一个值 let johnsAddress = Address() johnsAddress.buildingName = "The Larches" johnsAddress.street = "Laurel Street" john.residence?.address = johnsAddress // if let johnsstreet = john.residence?.address?.street { print("John's street name is \(johnsstreet).") } else { print("Unable to retrieve the address.") } // Prints "John's street name is Laurel Street."
- 方法返回可选项的响应链
- 示例代码块
if let buildingIdentifier = john.residence?.address?.buildingIdentifier() { print("John's building identifier is \(buildingIdentifier).") } // Prints "John's building identifier is The Larches." // 要执行更深层的响应链,如下 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\".") } } // Prints "John's building identifier begins with "The"." // 注意:`?` 是加在 `()` 之后因为返回值才是可选项,而不是方法名之后
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。