Swift: Implicitly Unwrapped Optionals (Неявно распакованные опционалы)

В случае если вы уверены, что optional значение после инициализации не равно nil — есть Implicitly Unwrapped Optionals, неявно распакованные опционалы, обозначаются с помощью того же восклицательного знака, но уже при определении типа, к примеру Int!

Хоть мы по прежнему можем проверить на nil (в отличии от Int), но теперь делать это не обязательно (для отмены проверок и постоянного использования ! все и затеяно)

Рассмотрим поподробней зачем все-таки ввели этот тип
1) для переменных, которые мы инициализируем не в init()

Мы не можем buttonOriginalWidth определить просто как CGFloat, т.к. на момент окончания инициализации мы не знаем какая ширина, мы получим эти данные посредством viewDidLoad, мы в этом уверены, и не хотим каждый раз приводить CGFloat? к CGFloat

2) Для работы с методами из UIKit API.
Большинство методов из API должны возвращать обьекты, которые вроде бы должны иметь значение, но гипотетически могут быть и null (т.к. любой Objective-C обьект унаследован от NSObject и может быть null). И по умолчанию все обьекты используемые в качестве параметров из API должны быть объявлены именно как неявно распакованные (Implicitly Unwrapped Optionals).
На момент написания, вышел Swift 1.2 и Apple причесала свой код. Так что мы можем наслаждаться API вида

а ведь совсем недавно было

В глазах от обилия знаков препинания не рябит? Помочь решить проблему стало введение атрибутов nullable и nonnull. Теперь в Objective-C любую переменную или метод можно пометить этими атрибутами.

Таким образом nullable будет определен как Тип?, а nonnull просто как Тип, если же ни один из атрибутов не выставлен — как Тип!
Т.е. Objective-C код

будет в swift воспринят как

А такой

Как

Более подробно можно глянуть в официальном блоге по Swift
https://developer.apple.com/swift/blog/?id=25

Проверим на практике как соотносятся друг с другом обычный тип, optional и Implicitly Unwrapped Optional

Запустим этот код в playground

На выходе мы получим

Optional(7) Swift.Optional

Как мы видим, Int? на самом деле имеет тип Swift.Optional, заглянув внутрь Swift.Optional мы видим что это generic перечисление, которое может принимать два вида значений — None, или значение типа T

Вывод идентичен
Optional(7) Swift.Optional
Значит optional сохраняет свой тип при присвоении новой переменной

В обоих случаях выведется «7 Swift.Int», распаковывая optional с помощью оператора ! мы получаем чистый тип по умолчанию, так что можно не указывать при определении переменной ее тип

Здесь так же идентичный вывод
7 Swift.ImplicitlyUnwrappedOptional

Таким образом, чтобы получить Implicitly Unwrapped Optional из optional’а, необходимо явно указать <Тип>! при объявлении переменной, но неважно указываем мы ! для присваиваемой переменной или нет

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *