【问题标题】:Swift Optional chainingSwift 可选链
【发布时间】:2015-09-25 06:04:57
【问题描述】:

此代码来自 Apple 的新书。我的问题是:为什么“let roomCount = john.residence?.numberOfRooms”是 nil,我认为 .numberOfRooms 应该是 1 但在 xcode 中它说是 nil 我只是不明白为什么是 nil。如果有人能澄清我这将是真棒。先感谢您。

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}

let john = Person()

let roomCount = john.residence?.numberOfRooms

john.residence = Residence()

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.")
}

【问题讨论】:

    标签: ios swift


    【解决方案1】:
    let roomCount = john.residence?.numberOfRooms
    

    在这一行中,roomCount 必须为 nil,因为您没有设置居住实例变量。 roomCount 在 john.residence = Residance() 之后不为零。

    好吧

    let roomCount = john.residence?.numberOfRooms
    

    是这样的

    let roomCount: Int! = nil
    
    if let unwrappedResidence = john.residence
    {
        roomCount = unwrappedResidence.numberOfRooms
    }
    

    所以如果 Residence 为 nil,则 roomCount 为 nil。

    【讨论】:

    • 感谢您的回答。但它怎么能访问 .numberOfRooms 呢?
    • 它无权访问房间数。这就是可选链接的重点。如果住宅不是零,它只能访问房间数量。如果住宅为零,则房间数为零。如果你说let roomCount=john.residence!.numberOfRooms 你会得到一个意外发现的 nil 运行时异常
    【解决方案2】:

    residence 在您尝试使用时尚未初始化:

    let roomCount = john.residence?.numberOfRooms
    

    所以这将始终打印nil,因为residence 没有可返回的内容。

    如果你想使用.numberOfRooms 首先初始化你的residence 实例并这样使用它:

    let john = Person()
    john.residence = Residence()
    let roomCount = john.residence?.numberOfRooms  // 1
    

    另一种方法是将其初始化到您的 Person 类中:

    class Person {
        var residence = Residence()
    }
    

    现在你可以这样使用.numberOfRooms了:

    let john = Person()
    let roomCount = john.residence.numberOfRooms  // 1
    

    【讨论】:

    • 感谢您的回答。但是,当我输入“let roomCount = john.residence?.numberOfRooms”时,为什么我可以访问 .numberOfRooms 而不是我分配的值 1。对不起,我很困惑,我只是不明白。
    • 因为numberOfRooms Residence 类的属性,所以您可以使用. 访问它
    • 是的,但是该属性的值为 1,我只是不明白为什么当该属性的值为 1 时为 nil。
    • 我现在明白了,因为 Residence 还没有被初始化,这就是为什么 Residence 是 nil 并且 .numberOfRooms 也是 nil 并且在 john.residence = Residence() 之后不再是 nil 的原因。我花了一段时间才得到它。非常感谢!
    【解决方案3】:

    在示例中,let john = Person() 行创建了一个类型为 Person 的对象 john

    Person 类型由可选属性 residence 组成,即var residence: Residence?

    这里 residencenil,因为类型 Residence 尚未初始化。但是即使 residence 是 nil 也可以访问它的属性 numberOfRooms(因为这里使用了 Optional Chaining)并且访问它的结果是 nil

    let roomCount = john.residence?.numberOfRooms
    

    之后当residence被初始化并赋值时,

    john.residence = Residence()
    

    现在,john.residence 对象已初始化,当访问其 numberOfRooms 属性时,它返回默认分配值 1。

    在 swift 中,可选类型的属性都可以访问,无论它们是否为 nil(已初始化或未初始化)。

    可选链接

    可选链是查询和调用当前可能为 nil 的可选的属性、方法和下标的过程。如果 optional 包含值,则属性、方法或下标调用成功; 如果可选项为 nil,则属性、方法或下标调用返回 nil。多个查询可以链接在一起,如果链中的任何链接为 nil,则整个链都会优雅地失败。

    Find reference here

    【讨论】:

      猜你喜欢
      • 2016-11-17
      • 2017-07-08
      • 1970-01-01
      • 2023-03-24
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多