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.