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

В Свифт, что делает! символ означает в сигнатуре функции?

В сигнатуре Swift-функции, что означает ! после аргумента? В частности, означает ли это, что аргумент нужно развернуть до того, как он будет передан, или что он распакуется (автоматически) по мере его прохождения. Вот пример:

func annotationButtonTUI(sender: UIButton!) { }

В этом случае функция является мишенью для UIButton, поэтому все, что происходит с !, происходит автоматически.

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

4b9b3361

Ответ 1

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

Вы видите неявно развернутые опции в API, импортированные из ObjC, потому что это самое близкое приближение Swift объекта, который ожидается там, но который может быть равен нулю. Это компромисс для импортированного API - вы можете обращаться к этим переменным напрямую, как в ObjC, и вы можете протестировать их для nil, используя необязательный синтаксис Swift. (Более подробно об этом можно найти в разделе Разговоры о расширенной совместимости от WWDC14.) Этот шаблон также относится к объявлениям IBAction, вставленным в Interface Builder, поскольку эти методы фактически вызывается из кода ObjC тоже.

Как вы, кажется, подозревали, Swift обертывает возможное значение nil в необязательном при соединении с ObjC, но ! в объявлении реализации функции разворачивает значение, чтобы вы могли использовать его напрямую. (На свой страх и риск.)

Начиная с Swift 1.2 (Xcode 6.2 в Spring 2015) API ObjC можно аннотировать с помощью nonnull и nullable, и в этом случае интерфейс Swift для этих API использует либо необязательный тип, либо полностью необязательный тип. (И так как Swift 2.0/Xcode 7.0, почти все API Apple проверены для использования аннотаций с нулевым значением, поэтому их подписи Swift больше не используют !.)

Что менее известно об этом, так это то, что вы можете изменять опциональность параметров при реализации собственных функций Swift, вызываемых ObjC. Если вы хотите, чтобы компилятор обеспечивал соблюдение того, что sender в вашем методе действий никогда не может быть nil, вы можете отключить ! от типа параметра. Если вы хотите, чтобы компилятор удостоверился, что вы всегда проверяете параметр, измените значение ! на a ?.

Ответ 2

Восклицательный знак после объявления типа в сигнатурах метода Swift означает, что параметр является Неявно Unwrapped Необязательный. Это означает, что это Необязательный тип (который обычно обозначается как ? после типа), который распаковывается каждый раз, когда вы обращаетесь к нему в тело метода. Не так, как это принято. Это как если бы вы использовали принудительное разворачивание - sender!.titleLabel - каждый раз, когда вы его используете, но вы не должны каждый раз набирать восклицательный знак - следовательно, неявно разворачиваться необязательно.

Из С помощью Swift с Cocoa и Objective-C, раздел Работа с нолем:

Так как Objective-C не гарантирует каких-либо ограничений для объекта, то Swift делает все классы в типах аргументов и возвращаемых типах необязательными в импортированных API Objective-C. Прежде чем использовать объект Objective-C, вы должны убедиться, что он отсутствует.

Неявно развернутый необязательный параметр позволяет обрабатывать его в коде Swift, как обычный тип значения, с оговоркой, что доступ к ней, когда он nil, прервет вашу программу с ошибкой во время выполнения. Вы защищаете это, используя if statements, необязательная привязка или необязательная цепочка.

Неявно развернутые опции являются прагматичным компромиссом, чтобы сделать работу в гибридной среде, которая должна взаимодействовать с существующими фреймами Cocoa и их соглашениями более приятными, а также позволять поэтапную миграцию в более безопасную парадигму программирования - без нулевых указателей - Быстрый компилятор. Youll встретит их во всех API Cocoa, но также есть некоторые варианты использования для них в чистом Swift, как описано в Почему создать "Неявно отключенные опции" ,