欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Swift - Optional Chaining

程序员文章站 2022-06-08 09:22:46
...

Swift 的可选绑定类似于 OC 中的消息为 nil,但是运用于所有类型,能够被检测成功或失败

Query & Call

Property / Function / Subscript

强制展开的替代方案: 可选绑定

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
    var rooms = [Room]()
}

// 强制展开,如果可选为 nil 运行时强制解包将会报错
let roomCount = john.residence!.numberOfRooms

// 可选绑定
if let roomCount = john.residence?.numberOfRooms {
     print("John's residence has \(roomCount) room(s).")   
}else {
     print("Unable to retrieve the number of rooms.")
}

通过可选绑定访问属性

let someAddress = Address()
someAddress.buildingNumber = "29"
someAddress.street = "Acacia Road"
john.residence?.address = someAddress

由于代码 john.residence = nil,分配可选时 = 右边不执行

func createAddress() -> Address {
    print("Function was called.")
    
    let someAddress = Address()
    someAddress.buildingNumber = "29"
    someAddress.street = "Acacia Road"

    return someAddress
}
// 不打印 Function was called,既没有调用 createAddress()
john.residence?.address = createAddress()

通过可选绑定访问方法

func printNumberOfRooms() {
    print("The number of rooms is \(numberOfRooms)")
}

// 可选绑定返回 Void? 即使 john.residence != nil,返回值也为空 
if john.residence?.printNumberOfRooms() != nil {
// if (john.residence?.address = someAddress) != nil
// 其中无论赋值成不成功,返回值均为 nil
    print("It was possible to print the number of rooms.")
}else {
    print("It was not possible to print the number of rooms.")
}
// 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.")
}
  • 访问可选类型的下标
var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0] += 1
testScores["Brian"]?[0] = 72

多级可选

多个查询能够被链接在一起,当连接中的绑定已经为 nil,则整条链失效

  • 如果 optional.Int,始终返回 Int?,无论有多少层
  • 如果 optional.Int?,始终返回 Int?,无论有多少层
if let johnStreet = 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).")
}
// Print "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"."

由于不是方法本身可选,所以不是在 "()" 前面加问号

转载于:https://www.jianshu.com/p/3a4c32b5feff