Swift 嵌套非可选结构给出可选

Swift nested non-optional structure gives optional

我有以下代码:

struct Product {
    var image: URL!
    var title: String!
    var price: Price!
    var rating: Float!
    var url: URL!
}

struct Price {
    var value: Double!
    var currency: String!  // should be enum
}

稍后我用以下方法初始化 Product

product = Product(
    image: URL(string: "...")!,
    title: "...",
    price: Price(
        value: 5.99,
        currency: "CAD"
    ),
    rating: 4.5,
    url: URL(string: "...")!
)

在运行时,product.price 的类型是 Price? 我觉得这很奇怪,因为它是隐式解包的。

我试过给 Price 一个 init() 方法,结果相同。我也试过在 Product 定义中使用 var price: Price! = Price(value: 0, currency: "CAD"),结果相同。 (我向 Price 添加了一个成员初始化器。)

这是怎么回事?

可能是因为在 Swift 中有 3 个隐式展开的可选值由普通的 Optionals 支持。

Proposal for abolishing IUO:

However, the appearance of ! at the end of a property or variable declaration's type no longer indicates that the declaration has IUO type; rather, it indicates that (1) the declaration has optional type, and (2) the declaration has an attribute indicating that its value may be implicitly forced. (No human would ever write or observe this attribute, but we will refer to it as @_autounwrapped.) Such a declaration is referred to henceforth as an IUO declaration.

During runtime, product.price is of type Price? I find this weird since it's explicitly set to be non-optional

不,您明确将其设置为可选:

struct Product {
  var image: URL! // <-- Explicitly marked as optional via '!'
}

如果您希望它是非可选的,请不要通过 !?:

将其标记为可选
struct Product {
  var image: URL // <-- not marked as optional
}

!? 都是可选的。唯一的区别是后者需要显式解包(if let),而前者是自动解包(如果使用不当可能导致崩溃)。