as
usado para upcasting e conversão de tipo para tipo com ponte
as?
usado para fundição segura, retorna nulo se falhar
as!
usado para forçar o lançamento, travar se falhar
Nota:
as!
não pode converter o tipo bruto para opcional
Exemplos:
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?)
Exemplo
var age: Int? = nil
var height: Int? = 180
Adicionando um ?imediatamente após o tipo de dados, você informa ao compilador que a variável pode conter um número ou não. Arrumado! Observe que realmente não faz sentido definir constantes opcionais - você pode definir seu valor apenas uma vez e, portanto, seria capaz de dizer se seu valor será nulo ou não.
Quando devemos usar "?" e quando "!"
digamos que temos um aplicativo simples baseado em UIKit. temos algum código em nosso controlador de visualização e queremos apresentar um novo controlador de visualização em cima dele. e precisamos decidir empurrar a nova visualização na tela usando o controlador de navegação.
Como sabemos, cada instância de ViewController possui um controlador de navegação de propriedade. Se você estiver construindo um aplicativo baseado em controlador de navegação, esta propriedade do controlador de visualização mestre do seu aplicativo é definida automaticamente e você pode usá-lo para enviar ou abrir controladores de visualização. Se você usar um único modelo de projeto de aplicativo - não haverá um controlador de navegação criado automaticamente para você, então o controlador de visualização padrão do seu aplicativo não terá nada armazenado na propriedade navigationController.
Tenho certeza de que você já adivinhou que este é exatamente o caso de um tipo de dados opcional. Se você marcar UIViewController, verá que a propriedade está definida como:
var navigationController: UINavigationController? { get }
Portanto, vamos voltar ao nosso caso de uso. Se você sabe com certeza que seu controlador de visualização sempre terá um controlador de navegação, você pode ir em frente e forçar o desempacotamento:
controller.navigationController!.pushViewController(myViewController, animated: true)
Quando você coloca um! por trás do nome da propriedade, você diz ao compilador que não me importo se esta propriedade é opcional, eu sei que quando este código for executado sempre haverá um armazenamento de valor, portanto, trate este opcional como um tipo de dados normal. Bem, isso não é bom? O que aconteceria se não houvesse um controlador de navegação para o controlador de visualização? Se você sugeriu que sempre haverá um valor armazenado no navigationController estava errado? Seu aplicativo irá falhar. Simples e feio assim.
Então, use! somente se você tiver 101% de certeza de que isso é seguro.
Que tal se você não tem certeza de que sempre haverá um controlador de navegação? Então você pode usar? em vez de um !:
controller.navigationController?.pushViewController(myViewController, animated: true)
O que ? por trás do nome da propriedade diz ao compilador que não sei se esta propriedade contém nil ou um valor, então: se ela tiver valor, use-a e, caso contrário, considere a expressão inteira nil.Efetivamente, o? permite que você use essa propriedade apenas no caso de haver um controlador de navegação. Não se verifica de qualquer tipo ou fundições de qualquer tipo. Esta sintaxe é perfeita quando você não se importa se tem um controlador de navegação ou não, e deseja fazer algo apenas se houver.
Muito obrigado a Fantageek