as
используется для преобразования и преобразования типа в мостовой тип
as?
используется для безопасного литья, в случае неудачи вернуть ноль
as!
используется для принудительного литья, сбой в случае неудачи
Заметка:
as!
не может привести исходный тип к необязательному
Примеры:
let rawString: AnyObject = "I love swift"
let optionalString: AnyObject? = "we love swift"
let nilString: AnyObject? = (nil as String?)
let rawInt: AnyObject = Int(3)
let optionalInt: AnyObject? = Int(3)
let nilInt: AnyObject? = (nil as Int?)
пример
var age: Int? = nil
var height: Int? = 180
Добавив ? сразу после типа данных вы сообщаете компилятору, что переменная может содержать число или нет. Аккуратно! Обратите внимание, что на самом деле нет смысла определять необязательные константы - вы можете установить их значение только один раз, и поэтому вы сможете сказать, будет ли их значение нулем или нет.
Когда мы должны использовать "?" и когда "!"
допустим, у нас есть простое приложение на основе UIKit. у нас есть некоторый код в нашем контроллере представления, и мы хотим представить новый контроллер представления поверх него. и нам нужно решить вывести новое представление на экран с помощью контроллера навигации.
Как мы знаем, каждый экземпляр ViewController имеет контроллер навигации по свойствам. Если вы создаете приложение на основе контроллера навигации, это свойство главного контроллера представления вашего приложения устанавливается автоматически, и вы можете использовать его для отправки или вывода контроллеров представления. Если вы используете один шаблон проекта приложения - для вас не будет автоматически создан контроллер навигации, поэтому в контроллере представления по умолчанию вашего приложения не будет ничего, хранящегося в свойстве navigationController.
Я уверен, что вы уже догадались, что это как раз тот случай, когда используется дополнительный тип данных. Если вы проверите UIViewController, вы увидите, что свойство определяется как:
var navigationController: UINavigationController? { get }
Итак, вернемся к нашему варианту использования. Если вы точно знаете, что ваш контроллер представления всегда будет иметь контроллер навигации, вы можете развернуть его принудительно:
controller.navigationController!.pushViewController(myViewController, animated: true)
Когда вы ставите! за именем свойства вы говорите компилятору, что меня не волнует, что это свойство является необязательным, я знаю, что при выполнении этого кода всегда будет хранилище значений, поэтому относитесь к нему как к обычному типу данных. Ну разве это не мило? Но что произойдет, если к вашему контроллеру представления не будет контроллера навигации? Если вы предположили, что в navigationController всегда будет храниться значение, было ошибкой? Ваше приложение выйдет из строя. Вот так просто и безобразно.
Итак, пользуйтесь! только если вы на 101% уверены, что это безопасно.
А если вы не уверены, что контроллер навигации всегда будет? Тогда можно использовать? вместо!:
controller.navigationController?.pushViewController(myViewController, animated: true)
Что за ? за именем свойства сообщает компилятору, что я не знаю, содержит ли это свойство nil или значение, поэтому: если оно имеет значение, используйте его, а в противном случае просто рассмотрите все выражение nil. Эффективно? позволяет использовать это свойство только в случае наличия контроллера навигации. Никаких проверок или отливок любого рода. Этот синтаксис идеален, когда вам все равно, есть ли у вас контроллер навигации или нет, и вы хотите что-то делать, только если он есть.
Огромное спасибо Fantageek