简体   繁体   English

Swift嵌套的非可选结构提供了可选

[英]Swift nested non-optional structure gives optional

I have the following code: 我有以下代码:

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
}

I later initialize a Product with: 稍后,我使用以下方法初始化Product

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

During runtime, product.price is of type Price? 在运行时, product.price的类型为Price? I find this weird since it's implicitly unwrapped. 我发现这很奇怪,因为它已隐式展开。

I've tried giving Price an init() method, with the same results. 我尝试给Price一个init()方法,其结果相同。 I've also tried using var price: Price! = Price(value: 0, currency: "CAD") 我也尝试使用var price: Price! = Price(value: 0, currency: "CAD") var price: Price! = Price(value: 0, currency: "CAD") in the Product definition, with the same results. var price: Price! = Price(value: 0, currency: "CAD") Product定义中的var price: Price! = Price(value: 0, currency: "CAD") ,结果相同。 (I add a memberwise initializer to Price .) (我向Price添加了一个成员初始化器。)

What's going on here? 这里发生了什么?

During runtime, product.price is of type Price? 在运行时,product.price的类型为Price? I find this weird since it's explicitly set to be non-optional 我发现这很奇怪,因为它已明确设置为非可选

No, you explicitly set it to be optional : 不,您明确将其设置为可选

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

if you want it to be non-optional, do not mark it as optional via ! 如果您希望它不是可选的,请不要通过!将其标记为可选! or ? 还是? :

struct Product {
  var image: URL // <-- not marked as optional
}

Both ! ! and ? ? are optionals. 是可选的。 The only difference being that the latter needs to be explicitly unwrapped ( if let ) while the former is automatically unwrapped (potentially leading to crashes if used incorrectly). 唯一的区别是后者需要显式地解包( if let ),而前者则需要自动解包(如果使用不正确,有可能导致崩溃)。

Perhaps because in Swift 3 implicitly unwrapped optionals are backed by ordinary Optional s. 可能是因为在Swift 3中,隐式解开的options被普通的Optional支持。

Proposal for abolishing IUO : 废除IUU的提案

However, the appearance of ! 但是,外观! at the end of a property or variable declaration's type no longer indicates that the declaration has IUO type; 在属性或变量声明的类型的末尾不再指示该声明具有IUO类型; 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. 相反,它指示(1)声明具有可选类型,并且(2)声明具有指示其值可以隐式强制的属性。 (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. (没有人会写或观察该属性,但我们将其称为@_autounwrapped。)此后,此声明称为IUO声明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM