Подтвердить что ты не робот

Двойное восклицание!! отметить в Свифт?

Я знаю определение для одного восклицательного знака, но два?

Сегодня я кодировал и компилятор "заставлял" меня добавить еще один! к моему предложению:

mySignal.subscribeNext({
        (value: AnyObject!) -> () in
        let list: RACSequence = value["myObject"]!!.rac_sequence
        ...

Если я использую только один! mark, проект не компилируется, что дает мне ошибку: "Значение необязательного типа" AnyObject "? не разворачивается, вы хотели использовать '!' или '?'?" Затем я добавляю еще один! и все работает.

Что означают восклицательные знаки два в Swift?

4b9b3361

Ответ 1

Вы сохраняете AnyObject! в словаре, поэтому вы сохраняете необязательное значение. Слои словаря всегда возвращают необязательное значение, которое вы храните, поэтому вы получаете необязательный вариант, поэтому вам нужно два!, чтобы развернуть его дважды.

Ответ 2

Это странный артефакт использования типа AnyObject вместо явного типа словаря. Обычно монада, как опция (спасибо user2864740) реализует операцию связывания с сигнатурой типа Optional<T>.bind(f: T -> Optional<U>) -> Optional<U>.

Это делает так, что, когда вы получаете доступ к необязательному члену необязательного значения, вы не получаете двойной-необязательный, который вам нужно развернуть, как лук, с каждым уровнем доступа.

Если вы делаете аналогичный пример с явным словарем, вы увидите, что результирующий тип будет всего одним слоем необязательного:

import UIKit

let anyDict: AnyObject? = ["foo" : 34, "bar" : 13]
let anyElement = anyDict?["foo"]
print(anyElement) // Optional(Optional(34))

let dict: [String : Int]? = ["foo" : 34, "bar" : 13]
let element = dict?["foo"]
print(element) // Optional(34)

Непонятно, почему это происходит с AnyObject, но я не считаю это предполагаемым поведением.