2016-12-12 3 views
0

У меня есть следующий код:Swift вложенная не опциональным структура дает опционально

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(), с теми же результатами. Я также пробовал использовать var price: Price! = Price(value: 0, currency: "CAD") в определении Product с теми же результатами. (Я добавляю элементный инициализатор в Price.)

Что здесь происходит?

+1

Почему свойства struct неявно разворачиваются в первую очередь? Это не ясно. Так как вы все равно разворачиваете значения, вы должны просто использовать необязательные свойства и использовать инициализатор по порядку. – Moritz

+0

Как вы проверили, что * "' product.price' имеет тип 'Price?' "* - Обратите внимание, что ImplicitlyUnwrappedOptional больше не является отдельным типом в Swift 3. См. Например. http://stackoverflow.com/questions/39537177/swift-3-incorrect-string-interpolation-with-implicitly-unwrapped-optionals или http://stackoverflow.com/questions/39633481/implicitly-unwrapped-optional-assign- в-Xcode-8. –

+0

Я использую не-необязательные свойства, и он исправляет проблемы, которые я испытывал. По-прежнему странно, что он не бросает никаких ошибок, правда? Я проверил использование отладчика. ('print product.price') –

ответ

5

Во время эксплуатации цена продукта.цены Цена? Я нахожу это странным, так как это явно установлено быть не опциональным

Нет, вы явно установить его, чтобы быть опциональный:

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

, если вы хотите, чтобы быть не обязательно, не пометить его как опционально через ! или ?:

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

Оба ! и ? являются опциями. Единственное отличие состоит в том, что последний должен быть явно развернут (if let), в то время как первый автоматически распаковывается (потенциально приводя к сбоям при неправильном использовании).

+0

А я вижу, это очищает вещи. Благодаря! –

1

Возможно, потому что в Swift 3 неявно развернутых опциональных элементах поддерживаются обычные Optional s.

Proposal for abolishing IUO:

Однако появление! в конце типа объявления свойства или переменной больше не указывает, что декларация имеет тип IUO; скорее, это указывает, что (1) объявление имеет необязательный тип, и (2) объявление имеет атрибут, указывающий, что его значение может быть принудительно принудительно. (Ни один человек никогда не напишет или не увидит этот атрибут, но мы будем называть его как @_autounwrapped.) Такая декларация в дальнейшем упоминается как декларация IUO.

Смежные вопросы