Daniel Que
Daniel Que

Reputation: 1734

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(
    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? I find this weird since it's implicitly unwrapped.

I've tried giving Price an init() method, with the same results. I've also tried using var price: Price! = Price(value: 0, currency: "CAD") in the Product definition, with the same results. (I add a memberwise initializer to Price.)

What's going on here?

Upvotes: 0

Views: 152

Answers (2)

hnh
hnh

Reputation: 14795

During runtime, product.price is of type 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).

Upvotes: 5

Andreas
Andreas

Reputation: 2715

Perhaps because in Swift 3 implicitly unwrapped optionals are backed by ordinary 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.

Upvotes: 1

Related Questions