不强制展开打印 属性 不会在 Swift 中触发运行时错误

Printing without force-unwrapping property doesn't trigger runtime error in Swift

我有下面的代码,它工作正常,但我希望行 print(john.residence!.numberOfRooms) 崩溃,因为我的 numberOfRooms 变量有 nil 值,我没有使用强制将其值作为参数传递给 print() 时换行。任何人都可以解释为什么这不会触发运行时错误并安全地打印 nil 吗?

class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms: Int?
}

let john = Person()

john.residence = Residence()

print(john.residence!.numberOfRooms)

您正在做的事情叫做可选链接。可选链接和强制展开都做同样的事情,但是:

The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.

“The Swift Programming Language (Swift 2.2).” iBooks. https://itun.es/br/jEUH0.l

您正在强制展开 .residence 属性,它不是 nil:它包含一个 Residence 实例,它有 .numberOfRooms 属性 设置为 nil 因为它没有被初始化。由于您没有强制展开它,因此由于可选链接,不会给出任何错误。尝试强制展开 .numberOfRooms 属性 而不是得到一个错误:

print(john.residence!.numberOfRooms!)

或者,您可以删除以下行以将 .residence 设置为 nil

john.residence = Residence()

这样 john 没有 .residence,因此尝试强制解包会使 Swift 编译器抛出运行时错误。

您的应用程序不会崩溃,因为您使用 ? 定义了 属性 numberOfRooms。这意味着它也将允许空值。

使用 ! 而不是 ?。这个语句肯定会崩溃。

 print(john.residence!.numberOfRooms)

访问此 link 它会帮助您了解 ?和 !.
Difference Between ? and ! in Swift Language?