Swift: что такое модификатор принудительного типа (!) для

В быстрой документации объясняется цель! оператор unboxing на дополнительных типах,

var optionalString : String? = "optional"
var regularString: String = optionalString!

но они использовали его сами по определению типов (String!), без явного объяснения, которое я могу найти.

Пример:

func takesBang(value:String!) -> String {
    if !value {
        return "nil value, without the safe syntax"
    }

    return "This works"
}

var unsafe:String!
takesBang(unsafe) // yields "nil value, without the safe syntax"

Строка! тип не приводит к распаковке необязательного типа, но только, кажется, устраняет необходимость в дополнительном синтаксисе (?.). Apple использует это в своих собственных примерах, но, похоже, только отрицает дополнительные механизмы безопасности (указатели).

Может ли кто-нибудь объяснить цель/мотивацию? Это, как правило, небезопасно, поскольку вызывающему абоненту не нужно проверять или, по крайней мере, думать об их стоимости.

Ответы

Ответ 1

Оказывается, это был просто надзор над частью Apple, они проводили аудит классов и обновляли возвращаемые типы начиная с Beta 5.

Из примечаний к выпуску Beta 6:

"Большое количество API-интерфейсов Foundation проверено для необязательных соответствие, удаление значительного числа неявно развернутых с их интерфейсами. Это поясняет недействительность их свойства и аргументы/возвращающие значения их методов. Эта является постоянным усилием со времени бета-тестирования 5".

Ответ 2

В справочнике языков указано, что оба параметра ?, а также !, когда используются в объявлениях var, являются только синтаксическим сахаром (что означает, что они заменяются компилятором во время разбора). Они сопоставляются с Optional<T> (?) И ImplicitlyUnwrappedOptional<T> (!) Соответственно.

Хотя вам нужно использовать синтаксис if let maybeNil = someVar? { ... } для переменных типа Optional<T>, вам не нужно делать это с помощью неявно развернутых опций (как уже говорит название). Поскольку уже упоминавшийся плакат в fooobar.com/questions/381395/..., подразумеваемые разворачиваемые опции предназначены для использования с устаревшими API Objective-C, поскольку они не предоставляют достаточной информации для Swift.

Итак, как краткое описание:

var foo : SomeType? // should be read as var foo : Optional<SomeType>
var bar : SomeType! // should be read as var bar : ImplicitlyUnwrappedOptional<SomeType>

Использование ? и ! при работе с фактическими значениями в переменных является фактически отображением, которое можно прочитать таким образом, аналогичным вышеприведенным объявлениям:

foo?.somemethod() // if let maybeFoo = foo { maybeFoo.somemethod() }

foo!.somemethod() /* # Yeah I know for sure, that this is NOT nil ever ever… just call `somemethod` and kill me at runtime if it doesn't work out.

Ответ 3

Это обычно небезопасно, но используется для импортированных API Objective-C, которые уже небезопасны таким образом и не предоставляют достаточную информацию, чтобы решить, должны ли они быть необязательными или необязательными.

В не импортированных API, я бы не ожидал, что он будет использоваться много.