Optional Chaining

  • Optional Chaining自判断链,可以用来判断调用的目标属性、方法、附属脚本等是否为空。不为空为成功,为空则失败,返回nil。这个链状结构,称为自判断链
  • 自判断链接类似于拆包,在属性方法后跟问号。不同之处在于为空时强制拆包会崩溃,但是自判断链接会得到一个很安全的失败返回
    if let roomCount = john.residence?.numberOfRooms {
        print("John's residence has \(roomCount) room(s)")
    } else {
        print("Unable to retrieve the number of rooms")
    }
    
    numberOfRooms是nonoptional属性,而residence是optional属性,使用自判断链接可以使得到的roomCount变为optional属性,即当residence为空时不会崩溃而是直接返回一个空的numberOfRooms属性
  • 自判断链可以用来判断optional属性的nonoptional是否为空,如上residence为optional属性,而numberOfRooms定义时为nonoptional,但是roomCount接收到的非Int而是Int?,这就是自判断链的作用
  • 自判断链可以进行多层判断,在等号左边时使用如果该属性为空不会执行为空属性下的属性赋值。
  • 当给自判断链为空的属性赋值时,右边函数并不会执行,如下:
    func createAddress() -> Address {
        print("Function was called.")
    
        let someAddress = Address()
        someAddress.buildingNumber = "29"
        someAddress.street = "Acacia Road"
    
        return someAddress
    }
    john.residence?.address = createAddress()
    
    没有任何打印。
  • 没有return的函数实际上是返回一个void类型,也可以理解成一个空的tuple。而在自判断链中,所返回的void类型变为void?类型。也就是说可以使用if来判断是否是一个nil实例调用其方法,如果调用失败也不会崩溃。对于赋值属性也是如此。
    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 (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."
    
  • 多重自判断链
    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"."
    

你可能感兴趣的:(Optional Chaining)