Decorações variáveis ​​rápidas com “?” (ponto de interrogação) e “!” (ponto de exclamação)


106

Eu entendo que em Swift todas as variáveis ​​devem ser definidas com um valor e que, usando opcionais, podemos definir uma variável a ser definida nilinicialmente.

O que eu não entendo é o que definir uma variável com um !está fazendo, porque eu estava com a impressão de que isso "desembrulha" um valor de um opcional. Achei que, ao fazer isso, você estaria garantindo que havia um valor a ser desembrulhado nessa variável, que é o motivo pelo qual em IBActions e similares você o vê usado.

Então, simplesmente, para que serve a variável sendo inicializada quando você faz algo assim:

var aShape : CAShapeLayer!

E por que / quando eu faria isso?


Você faria isso para saber que uma variável não é nula depois de verificar esse fato.
Matthias

Não acho que isso deva ser marcado como uma duplicata. "O que é opcional?" não é a mesma pergunta que "Qual é a diferença entre os dois tipos de opcionais?" que é basicamente o que esta pergunta é
Jiaaro

@Jiaaro, mesmo nesse caso, já existem toneladas de perguntas sobre opcionais, opcionais implicitamente desembrulhados e assim por diante. Você também pode consultar este aqui: stackoverflow.com/questions/24272781/…
Jack

@JackWu Ok, mas tenho quase certeza de que essa pergunta não era uma duplicata quando foi feita. (foi perguntado uma semana inteira antes do seu exemplo, por exemplo)
Jiaaro

@Jiaaro Você fez uma boa observação, não percebi que era mais antigo ... talvez outro deva ser marcado como uma duplicata deste em vez disso ..
Jack

Respostas:


145

Em uma declaração de tipo, o !é semelhante ao ?. Ambos são opcionais, mas o !é um opcional "desembrulhado implicitamente" , o que significa que você não precisa desembrulhar para acessar o valor (mas ainda pode ser nulo).

Esse é basicamente o comportamento que já tínhamos no objetivo-c. Um valor pode ser nulo e você deve verificar por ele, mas você também pode acessar o valor diretamente como se não fosse um opcional (com a importante diferença de que se você não verificar nulo, você obterá um erro de tempo de execução)

// Cannot be nil
var x: Int = 1

// The type here is not "Int", it's "Optional Int"
var y: Int? = 2

// The type here is "Implicitly Unwrapped Optional Int"
var z: Int! = 3

Uso:

// you can add x and z
x + z == 4

// ...but not x and y, because y needs to be unwrapped
x + y // error

// to add x and y you need to do:
x + y!

// but you *should* do this:
if let y_val = y {
    x + y_val
}

7
Opcionais implicitamente desembrulhados são descritos em uma seção apropriadamente nomeada começando na página 56 de The Swift Programming Language .
Caleb

@Caleb Eu adicionei um link para a seção relevante dos documentos online onde mencionei opcionais não embrulhados implicitamente :)
Jiaaro

Ótima informação, obrigado. Geralmente amando a segurança que o Swift está nos impondo até agora, deve produzir muito menos bugs :).
Jason Renaldo

@Jiaaro: Muito obrigado por compartilhar. Faz o usuário entender perfeitamente pelo exemplo acima. !! :)
Esha

3
Acho que a frase " Este é basicamente o comportamento que já tínhamos em objetivo-c " pode ser confusa. Em Objective-C pode-se aceder a um nilvalor e realmente "trabalhar" com ele, em rápida acessar um opcional implicitamente desembrulhado Embora seja nula irá lançar uma exceção tempo de execução.
Sascha Wolf
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.