override func viewDidLoad() { super.viewDidLoad() //可选链 //可选链是访问或调用可选类型的属性, 方法, 下标的过程, 如果可选类型有值则调用成功, 否则返回 nil. //多个访问可以链接在一起, 其中一个访问失败,则整个链表失败. //1. 可选链作为另一种强制解包的方式 //表达形式: 在可选值后加 "?" //可选链和强制解包的区别: 可选链值为 nil 失败, 但是不会引起崩溃. //可选链的返回值总是为可选类型, 即使调用属性, 方法, 下标的返回值为非可选类型, 返回值类型是相应的可选类型 class Person { var residence: Residence? var name: String? } class Residence { var numberOfRooms = 1 } let john = Person() //直接强制解包会报错 // let roomCount = john.residence!.numberOfRooms //使用可选链, 在可选值后加 "?" let roomCount = john.residence?.numberOfRooms //residence 没有初始化, 默认为 nil if let roomNum = john.residence?.numberOfRooms { print("John's residence has \(roomNum) room(s).") } else { print("Unable to retrieve the number of rooms.") } // Prints "Unable to retrieve the number of rooms." //给 john.residence 赋一个实例对象, 它的值不再为 nil john.residence = Residence() //numberOfRooms 为非可选 Int 型, 但是在可选链中仍然返回可选类型 if let roomNum1 = john.residence?.numberOfRooms { print("John's residence has \(roomNum1) room(s).") } else { print("Unable to retrieve the number of rooms.") } // Prints "John's residence has 1 room(s)." //2. 为可选链定义 Model 类 //可以使用可选链, 访问复杂 Model的多个层级的属性, 方法, 下标 class PersonClass { var residence: ResidenceClass? } class ResidenceClass { 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 room 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 } } } //3. 通过可选链访问属性 //通过可选链获取属性 let johnSon = PersonClass() if let roomCount = johnSon.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 为 nil 赋值失败, 等号右边没有被调用 func createAddress() -> Address { print("Function was called.") let someAddress = Address() someAddress.buildingNumber = "29" someAddress.street = "Acacia Road" return someAddress } johnSon.residence?.address = createAddress() //4. 通过可选链调用方法 //可以用可选链调用一个函数,并检查是否调用成功,即使函数没有返回值 // func printNumberOfRooms() { // print("The number of rooms is \(numberOfRooms)") // } //用可选链调用函数时, 返回值是可选类型(void 会变为 void?) , 可以使用if 语句判断是否可以调用printNumberOfRooms() 方法 if johnSon.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 (johnSon.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." //5. 通过可选链获取下标 //可以使用可选链获取设置一个可选值的下标, 并检查下标调用是否成功 //用可选链获取下标, ? 放在括号前 if let firstRoomName = johnSon.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." //6. 获取可选类型的下标 //如果一个下标返回可选类型的值就像字典那样, 在闭括号后加 ? 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] //7. 连接多个层级的可选链 //用可选链获取一个值, 如果这个值是非可选的, 返回值会变为可选 if let johnsStreet = johnSon.residence?.address?.street { print("John's street name is \(johnsStreet).") } else { print("Unable to retrieve the address.") } // Prints "Unable to retrieve the address." //john.residence.address 为 nil 调用失败 let johnsAddress = Address() johnsAddress.buildingName = "The Larches" johnsAddress.street = "Laurel Street" johnSon.residence?.address = johnsAddress if let johnsStreet = johnSon.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." //8. 返回值为可选类型的 chain //可选链的调用函数的返回值也是可选类型 if let buildingIdentifier = johnSon.residence?.address?.buildingIdentifier() { print("John's building identifier is \(buildingIdentifier).") } // Prints "John's building identifier is The Larches." //如果想进一步对返回值使用可选链, 可以在方法的双括号后添加 ? if let beginsWithThe = johnSon.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"." }
Swift- 可选链
猜你喜欢
转载自blog.csdn.net/leecsdn77/article/details/80741161
今日推荐
周排行