Estou usando o Xcode 6 Beta 4. Tenho uma situação estranha em que não consigo descobrir como testar adequadamente os opcionais.
Se eu tiver um xyz opcional, é a maneira correta de testar:
if (xyz) // Do something
ou
if (xyz != nil) // Do something
Os documentos dizem para fazê-lo da primeira maneira, mas descobri que, às vezes, a segunda maneira é necessária e não gera um erro do compilador, mas outras vezes, a segunda maneira gera um erro do compilador.
Meu exemplo específico está usando o analisador XML GData em ponte para swift:
let xml = GDataXMLDocument(
XMLString: responseBody,
options: 0,
error: &xmlError);
if (xmlError != nil)
Aqui, se eu fizesse:
if xmlError
sempre retornaria verdadeiro. No entanto, se eu fizer:
if (xmlError != nil)
então funciona (como funciona no Objective-C).
Existe algo no XML do GData e a maneira como ele trata os opcionais que estão faltando?
Respostas:
No Xcode Beta 5, eles não permitem mais:
Isso produz um erro:
Você precisa usar um destes formulários:
fonte
Para adicionar às outras respostas, em vez de atribuir a uma variável com nome diferente dentro de uma
if
condição:você pode reutilizar o mesmo nome de variável assim:
Isso pode ajudar a evitar a falta de nomes de variáveis de criativos ...
Isso tira proveito do sombreamento variável suportado no Swift.
fonte
Uma das maneiras mais diretas de usar opcionais é o seguinte:
Supondo que
xyz
seja do tipo opcional, comoInt?
por exemplo.Dessa forma, você pode testar se
xyz
contém um valor e, se houver, trabalhar imediatamente com esse valor.Com relação ao erro do seu compilador, o tipo
UInt8
não é opcional (observe o número '?') E, portanto, não pode ser convertido emnil
. Verifique se a variável com a qual você está trabalhando é opcional antes de tratá-la como uma.fonte
Swift 3.0, 4.0
Existem principalmente duas maneiras de verificar opcional para zero. Aqui estão exemplos com comparação entre eles
1. se deixar
if let
é a maneira mais básica de verificar opcional para zero. Outras condições podem ser anexadas a essa verificação nula, separadas por vírgula. A variável não deve ser nula para se mover para a próxima condição. Se apenas a verificação nula for necessária, remova condições extras no código a seguir.Fora isso, se
x
não for nulo, o fechamento if será executado ex_val
estará disponível dentro. Caso contrário, o fechamento else será acionado.2. guarda deixe
guard let
pode fazer coisas semelhantes. Seu principal objetivo é torná-lo logicamente mais razoável. É como dizer Certifique-se de que a variável não seja nula; caso contrário, pare a função .guard let
também pode fazer a verificação de condição extra comoif let
.As diferenças são que o valor desembrulhado estará disponível no mesmo escopo
guard let
, conforme mostrado no comentário abaixo. Isso também leva a tal ponto que no fecho de outra pessoa, o programa tem de sair do escopo atual, porreturn
,break
etc.fonte
Do guia de programação rápida
Portanto, a melhor maneira de fazer isso é
e se você estiver usando a
xyz
instrução if se. Em seguida, você pode desembrulhar axyz
instrução if na variável constantexyz
.Esta convenção é sugerida por
apple
e será seguida por devlopers.fonte
if xyz != nil {...}
.Embora você ainda precise comparar explicitamente um opcional
nil
ou usar a ligação opcional para extrair adicionalmente seu valor (ou seja, os opcionais não são implicitamente convertidos em valores booleanos), é importante observar que o Swift 2 adicionou aguard
instrução para ajudar a evitar a pirâmide de destruição ao trabalhar com vários valores opcionais.Em outras palavras, suas opções agora incluem a verificação explícita de
nil
:Ligação opcional:
E
guard
declarações:Observe como a ligação opcional comum pode levar a um recuo maior quando há mais de um valor opcional:
Você pode evitar esse aninhamento com
guard
instruções:fonte
nil
valor, mas concordo que a curva de aprendizado é um pouco íngreme. :)Extensão de Protocolo Swift 5
Aqui está uma abordagem usando a extensão de protocolo para que você possa incorporar facilmente uma verificação nula opcional:
Uso
fonte
swift
análogo dopythonistas
que tenta manter a linguagem em alguma forma de pureza pitônica. Minha vez? Acabei de colocar seu código no meu mix de utilitários.Agora você pode fazer rapidamente o seguinte, o que lhe permite recuperar um pouco do objetivo-c
if nil else
fonte
Em vez de
if
, o operador ternário pode ser útil quando você deseja obter um valor com base no fato de algo ser nulo:fonte
xyz == nil
expressão não funciona, masx != nil
funciona. Não sei porque.Outra abordagem, além de usar
if
ouguard
instruções para fazer a ligação opcional, é estenderOptional
com:ifValue
recebe um fechamento e o chama com o valor como argumento quando o opcional não é nulo. É usado desta maneira:Você provavelmente deve usar um
if
ou,guard
no entanto, essas são as abordagens mais convencionais (portanto familiares) usadas pelos programadores Swift.fonte
Uma opção que não foi especificamente abordada é usar a sintaxe de valor ignorado do Swift:
Gosto disso, pois a verificação
nil
parece deslocada em um idioma moderno como o Swift. Acho que a razão pela qual ela se sente deslocadanil
é basicamente um valor sentinela. Acabamos com os sentinelas em praticamente todos os outros lugares da programação moderna, entãonil
parece que isso também deveria acontecer.fonte
Você também pode usar
Nil-Coalescing Operator
Se
optionalValue
fornil
, atribui valor automaticamente adefaultValue
fonte
Este teste funcionou como esperado em todos os casos. BTW, você não precisa dos suportes
()
.fonte
if (xyz != nil)
.Se você tem condicional e gostaria de desembrulhar e comparar, que tal aproveitar a avaliação de curto-circuito da expressão booleana composta, como em
É verdade que isso não é tão legível como alguns dos outros posts sugeridos, mas faz o trabalho e é um tanto sucinto do que as outras soluções sugeridas.
fonte