Você pode usar
if
elet
juntos para trabalhar com valores que podem estar ausentes. Esses valores são representados como opcionais. Um valor opcional contém um valor ounil
indica que o valor está ausente. Escreva um ponto de interrogação (?
) após o tipo de um valor para marcar o valor como opcional.
Por que você deseja usar um valor opcional?
Respostas:
Um opcional no Swift é um tipo que pode conter um valor ou nenhum valor. Os opcionais são gravados anexando a
?
a qualquer tipo:Os opcionais (juntamente com os genéricos) são um dos conceitos Swift mais difíceis de entender. Por causa de como eles são escritos e usados, é fácil ter uma idéia errada do que são. Compare o opcional acima para criar uma String normal:
A partir da sintaxe, parece que uma String opcional é muito semelhante a uma String comum. Não é. Uma String opcional não é uma String com alguma configuração "opcional" ativada. Não é uma variedade especial de String. Uma String e uma String opcional são tipos completamente diferentes.
Aqui está a coisa mais importante a saber: Um opcional é um tipo de contêiner. Uma String opcional é um contêiner que pode conter uma String. Um Int opcional é um contêiner que pode conter um Int. Pense em um opcional como um tipo de parcela. Antes de abri-lo (ou "desembrulhar" no idioma dos opcionais), você não saberá se ele contém algo ou nada.
Você pode ver como os opcionais são implementados na Swift Standard Library digitando "Opcional" em qualquer arquivo Swift e clicando ⌘ nele. Aqui está a parte importante da definição:
Opcional é apenas um
enum
que pode ser um dos dois casos:.none
ou.some
. Se for.some
, existe um valor associado que, no exemplo acima, seria oString
"Olá". Um opcional usa Genéricos para atribuir um tipo ao valor associado. O tipo de uma String opcional não éString
, éOptional
ou mais precisamenteOptional<String>
.Tudo o que o Swift faz com os opcionais é mágico para tornar a leitura e a escrita de códigos mais fluentes. Infelizmente, isso obscurece a maneira como realmente funciona. Vou passar por alguns truques mais tarde.
Nota: falarei muito sobre variáveis opcionais, mas também é bom criar constantes opcionais. Marquei todas as variáveis com seus tipos para facilitar a compreensão dos tipos de tipos que estão sendo criados, mas você não precisa fazer isso em seu próprio código.
Como criar opcionais
Para criar um opcional, anexe a
?
após o tipo que você deseja agrupar. Qualquer tipo pode ser opcional, até mesmo seus próprios tipos personalizados. Você não pode ter um espaço entre o tipo e o?
.Usando opcionais
Você pode comparar um opcional
nil
para ver se ele possui um valor:Isto é um pouco confuso. Isso implica que um opcional é uma coisa ou outra. É nulo ou é "Bob". Isso não é verdade, o opcional não se transforma em outra coisa. Compará-lo a zero é um truque para tornar o código mais fácil de ler. Se um opcional for igual a zero, isso significa apenas que o enum está atualmente definido como
.none
.Somente opcionais podem ser nulos
Se você tentar definir uma variável não opcional como nula, receberá um erro.
Outra maneira de ver os opcionais é como um complemento às variáveis Swift normais. Eles são uma contrapartida de uma variável que é garantida como tendo um valor. Swift é uma linguagem cuidadosa que odeia ambiguidade. A maioria das variáveis é definida como não opcional, mas às vezes isso não é possível. Por exemplo, imagine um controlador de exibição que carrega uma imagem de um cache ou da rede. Pode ou não ter essa imagem no momento em que o controlador de exibição é criado. Não há como garantir o valor da variável de imagem. Nesse caso, você precisaria torná-lo opcional. Inicia como
nil
e quando a imagem é recuperada, o opcional recebe um valor.O uso de um opcional revela a intenção dos programadores. Comparado ao Objective-C, onde qualquer objeto pode ser nulo, o Swift precisa que você seja claro sobre quando um valor pode estar faltando e quando é garantido que ele existe.
Para usar um opcional, você o "desembrulha"
Um opcional
String
não pode ser usado no lugar de um realString
. Para usar o valor agrupado dentro de um opcional, você deve desembrulhá-lo. A maneira mais simples de desembrulhar um opcional é adicionar um!
após o nome opcional. Isso é chamado de "força de desembrulhar". Ele retorna o valor dentro do opcional (como o tipo original), mas se o opcional fornil
, causa uma falha no tempo de execução. Antes de desembrulhar, verifique se há um valor.Verificando e usando um opcional
Como você sempre deve verificar o valor nulo antes de desembrulhar e usar um opcional, este é um padrão comum:
Nesse padrão, você verifica se um valor está presente e, quando tiver certeza, é forçado a desembrulhá-lo em uma constante temporária para uso. Como isso é algo comum, o Swift oferece um atalho usando "if let". Isso é chamado de "ligação opcional".
Isso cria uma constante temporária (ou variável, se você substituir
let
porvar
), cujo escopo está apenas dentro das chaves do if. Como ter que usar um nome como "desempacotadoMealPreference" ou "realMealPreference" é um fardo, o Swift permite reutilizar o nome da variável original, criando um nome temporário no escopo do colcheteAqui está um código para demonstrar que uma variável diferente é usada:
A ligação opcional funciona verificando se o opcional é igual a zero. Caso contrário, desembrulha o opcional na constante fornecida e executa o bloco. No Xcode 8.3 e posterior (Swift 3.1), tentar imprimir um opcional como esse causará um aviso inútil. Use os opcionais
debugDescription
para silenciá-lo:Para que são opcionais?
Os opcionais têm dois casos de uso:
Alguns exemplos concretos:
middleName
ouspouse
em umaPerson
classeweak
propriedades em classes. O que eles apontam pode ser definido anil
qualquer momentoBoolean
Os opcionais não existem no Objective-C, mas há um conceito equivalente, retornando nulo. Métodos que podem retornar um objeto podem retornar nulo. Isso significa "a ausência de um objeto válido" e é frequentemente usado para dizer que algo deu errado. Ele funciona apenas com objetos Objective-C, não com primitivos ou tipos C básicos (enumerações, estruturas). O Objective-C geralmente tinha tipos especializados para representar a ausência desses valores (o
NSNotFound
que é realmenteNSIntegerMax
,kCLLocationCoordinate2DInvalid
para representar uma coordenada inválida-1
ou também é usado algum valor negativo). O codificador precisa conhecer esses valores especiais para que eles sejam documentados e aprendidos para cada caso. Se um método não pode tomarnil
como parâmetro, isso deve ser documentado. No Objetivo-C,nil
era um ponteiro, assim como todos os objetos eram definidos como ponteiros, masnil
apontavam para um endereço (zero) específico. Em Swift,nil
é um literal que significa a ausência de um determinado tipo.Comparando à
nil
Você costumava usar qualquer opcional como
Boolean
:Nas versões mais recentes do Swift, você precisa usar
leatherTrim != nil
. Por que é isso? O problema é que umBoolean
pode ser envolvido em um opcional. Se você temBoolean
assim:ele tem dois tipos de "false", um onde não há valor e outro onde ele tem um valor, mas o valor é
false
. Swift odeia ambiguidade, então agora você deve sempre verificar um opcional contranil
.Você pode se perguntar qual é o objetivo de um opcional
Boolean
? Como com outros opcionais, o.none
estado pode indicar que o valor ainda é desconhecido. Pode haver algo do outro lado de uma chamada de rede que leva algum tempo para ser pesquisado. Booleanos opcionais também são chamados de " Booleanos de Três Valores "Truques rápidos
O Swift usa alguns truques para permitir que os opcionais funcionem. Considere estas três linhas de código opcional com aparência comum;
Nenhuma dessas linhas deve compilar.
String
os tipos são diferentesVou examinar alguns dos detalhes de implementação de opcionais que permitem que essas linhas funcionem.
Criando um opcional
Usar
?
para criar um opcional é o açúcar sintático, ativado pelo compilador Swift. Se você quiser fazer isso da maneira mais longa, poderá criar um opcional como este:Isso chama
Optional
o primeiro inicializador,public init(_ some: Wrapped)
que infere o tipo associado do opcional do tipo usado entre parênteses.A maneira ainda mais longa de criar e definir um opcional:
Definir um opcional para
nil
Você pode criar um opcional sem valor inicial ou criar um com o valor inicial de
nil
(ambos têm o mesmo resultado).Permitir que os opcionais sejam iguais
nil
é ativado pelo protocoloExpressibleByNilLiteral
(nomeado anteriormenteNilLiteralConvertible
). O opcional é criado comOptional
o segundo inicializadorpublic init(nilLiteral: ())
,. Os documentos dizem que você não deve usarExpressibleByNilLiteral
nada além de opcionais, pois isso mudaria o significado de zero no seu código, mas é possível fazer isso:O mesmo protocolo permite definir um opcional já criado como
nil
. Embora não seja recomendado, você pode usar o inicializador literal nulo diretamente:Comparando um opcional para
nil
Os opcionais definem dois operadores "==" e "! =" Especiais, que você pode ver na
Optional
definição. O primeiro==
permite que você verifique se algum opcional é igual a zero. Dois opcionais diferentes definidos como .none sempre serão iguais se os tipos associados forem os mesmos. Quando você compara com zero, nos bastidores, o Swift cria um opcional do mesmo tipo associado, definido como .none e o utiliza para a comparação.O segundo
==
operador permite comparar dois opcionais. Ambos precisam ser do mesmo tipo e esse tipo precisa estar em conformidadeEquatable
(o protocolo que permite comparar as coisas com o operador "==" regular). Swift (presumivelmente) desembrulha os dois valores e os compara diretamente. Ele também lida com o caso em que um ou ambos os opcionais estão.none
. Observe a distinção entre comparar com onil
literal.Além disso, permite comparar qualquer
Equatable
tipo com uma embalagem opcional desse tipo:Nos bastidores, Swift envolve o não opcional como opcional antes da comparação. Também funciona com literais (
if 23 == numberFromString {
)Eu disse que existem dois
==
operadores, mas há um terceiro que permite que você coloquenil
no lado esquerdo da comparaçãoOpcionais de nomeação
Não existe uma convenção Swift para nomear tipos opcionais de maneira diferente dos tipos não opcionais. As pessoas evitam adicionar algo ao nome para mostrar que é opcional (como "optionalMiddleName" ou "possibleNumberAsString") e permitem que a declaração mostre que é um tipo opcional. Isso fica difícil quando você deseja nomear algo para reter o valor de um opcional. O nome "middleName" implica que é um tipo de String, portanto, quando você extrai o valor da String, geralmente pode acabar com nomes como "actualMiddleName" ou "desempacotadoMiddleName" ou "realMiddleName". Use a ligação opcional e reutilize o nome da variável para contornar isso.
A definição oficial
De "The Basics" na linguagem de programação Swift :
Para terminar, aqui está um poema de 1899 sobre opcionais:
Ontem, na escada
, conheci um homem que não estava lá.
Ele não estava lá hoje novamente
. Desejo, desejo que ele fosse embora.
Antigonish
Mais recursos:
fonte
if myString
não compila mais. Você precisaif myString != nil
. Veja a documentação .Vamos dar o exemplo de um
NSError
, se não houver um erro sendo retornado, você deseja torná-lo opcional para retornar Nil. Não faz sentido atribuir um valor a ele se não houver um erro.Isso também permite que você tenha um valor padrão. Assim, você pode definir um método como um valor padrão se a função não receber nada
fonte
func isNil<T>(t: T?) -> Bool { return t == nil }
retornarátrue
mesmo se houver um valor opcional que estejanil
na expressãoreturn x == 5
? O que há de tão especial em 5?Você não pode ter uma variável que aponte para o
nil
Swift - não há ponteiros nem ponteiros nulos. Mas em uma API, você geralmente deseja indicar um tipo específico de valor ou falta de valor - por exemplo, minha janela tem um delegado e, se sim, quem é? Os opcionais são a maneira segura e de memória do Swift para fazer isso.fonte
Fiz uma resposta curta, que resume a maioria dos itens acima, para limpar a incerteza que estava na minha cabeça como iniciante:
Ao contrário do Objective-C, nenhuma variável pode conter nulo no Swift; portanto, o tipo de variável Opcional foi adicionado (variáveis com o sufixo "?"):
A grande diferença é que as variáveis opcionais não armazenam valores diretamente (como as variáveis normais de Obj-C) contêm dois estados : " has a value " ou " has nil ":
Sendo assim, você pode verificar essas variáveis em diferentes situações:
Usando o "!" como sufixo, você também pode acessar os valores contidos neles, apenas se existirem . (ou seja, não é nulo ):
É por isso que você precisa usar "?" e "!" e não usar todos eles por padrão. (este foi o meu maior espanto)
Também concordo com a resposta acima: O tipo opcional não pode ser usado como booleano .
fonte
No objetivo C, variáveis sem valor eram iguais a 'nil' (também era possível usar valores 'nil' iguais a 0 e false); portanto, era possível usar variáveis em declarações condicionais (variáveis com valores iguais a 'TRUE 'e aqueles sem valores foram iguais a' FALSE ').
Swift fornece segurança de tipo, fornecendo 'valor opcional'. ou seja, evita erros formados de atribuir variáveis de tipos diferentes.
Portanto, no Swift, apenas booleanos podem ser fornecidos em instruções condicionais.
Aqui, mesmo que 'hw' seja uma string, ela não pode ser usada em uma instrução if como no objetivo C.
Para isso, ele precisa ser criado como,
fonte
O valor opcional permite mostrar a ausência de valor. Um pouco como NULL no SQL ou NSNull no Objective-C. Eu acho que isso será uma melhoria, pois você pode usar isso mesmo para tipos "primitivos".
Trecho de: Apple Inc. “A linguagem de programação Swift”. iBooks. https://itun.es/gb/jEUH0.l
fonte
nil
é apenas açúcar sintático para a constante enumOptionalValue<T>.None
(ondeT
é o tipo apropriado para o contexto em que você está usandonil
).?
é um atalho paraOptionalValue<T>.Some(T)
.Um opcional significa que Swift não tem certeza absoluta se o valor corresponde ao tipo: por exemplo, Int? significa que Swift não tem muita certeza se o número é um Int.
1) Se você tem certeza absoluta do tipo, pode usar um ponto de exclamação para forçá-lo a desembrulhá-lo, assim:
Se você forçar a desembrulhar um opcional e for igual a zero, poderá encontrar este erro de falha:
Isso não é necessariamente seguro, então, aqui está um método que pode evitar falhas caso você não tenha certeza do tipo e valor:
2) O opcional implicitamente desembrulhado
3) A declaração de guarda
A partir daqui, você pode prosseguir e usar a variável desembrulhada. Certifique-se de forçar a desembrulhar (com um!), Se tiver certeza do tipo da variável.
fonte
Quando comecei a aprender
Swift
, era muito difícil perceber o porquê opcional .Vamos pensar dessa maneira. Vamos considerar uma classe
Person
que possui duas propriedadesname
ecompany
.Agora vamos criar alguns objetos de
Person
Mas não podemos passar
Nil
paraname
Agora vamos falar sobre por que usamos
optional?
. Vamos considerar uma situação em que queremos adicionar oInc
nome da empresa comoapple
seráapple Inc
. Precisamos acrescentar oInc
nome da empresa e imprimir.Agora vamos estudar por que o opcional é implementado.
Vamos substituir
bob
portom
E parabéns! nós lidamos adequadamente com
optional?
Portanto, os pontos de realização são
nil
nil
.Obrigado ... Happy Coding
fonte
Vamos experimentar com o código abaixo do Playground . Espero ter uma ideia clara do que é opcional e o motivo de usá-lo.
fonte
Em https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html :
Para entender mais, leia o link acima.
fonte
Bem...
A principal diferença é que o encadeamento opcional falha normalmente quando o opcional é nulo, enquanto o desembrulhamento forçado aciona um erro de tempo de execução quando o opcional é nulo.
Para refletir o fato de que o encadeamento opcional pode ser chamado em um valor nulo, o resultado de uma chamada de encadeamento opcional é sempre um valor opcional, mesmo que a propriedade, o método ou o subscrito que você está consultando retorne um valor não opcional. Você pode usar esse valor de retorno opcional para verificar se a chamada de encadeamento opcional foi bem-sucedida (a opção retornada contém um valor) ou não teve êxito devido a um valor nulo na cadeia (o valor opcional retornado é nulo).
Especificamente, o resultado de uma chamada de encadeamento opcional é do mesmo tipo que o valor de retorno esperado, mas encapsulado em um opcional. Uma propriedade que normalmente retorna um Int retornará um Int? quando acessado através de encadeamento opcional.
Aqui está o tutorial básico em detalhes, pelo Apple Developer Committee: Encadeamento opcional
fonte
Um opcional no Swift é um tipo que pode conter um valor ou nenhum valor. Os opcionais são gravados anexando a ? para qualquer tipo:
Você pode consultar este link para obter conhecimento aprofundado: https://medium.com/@agoiabeladeyemi/optionals-in-swift-2b141f12f870
fonte
Aqui está uma declaração opcional equivalente no Swift:
Esta declaração cria uma variável chamada middleName do tipo String. O ponto de interrogação (?) Após o tipo de variável String indica que a variável middleName pode conter um valor que pode ser String ou nulo. Qualquer pessoa que observe esse código imediatamente sabe que middleName pode ser nulo. É auto-documentado!
Se você não especificar um valor inicial para uma constante ou variável opcional (como mostrado acima), o valor será automaticamente definido como nulo para você. Se preferir, você pode definir explicitamente o valor inicial como nulo:
Para obter mais detalhes, leia o link opcional abaixo.
http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values
fonte