Dia 12 - #100DaysOfSwift
Tags: ios, swift
Published: 2023-10-21 01:26:48

#Opcionais
Permitem que representemos um dado que não existe, mas que pode ou não vir a existir na memória.

---

##Unwrapping
Quando um dado é opcional regular o swift não nos permite acessá-lo sem antes verificar se ele é nil(não existe na memória) ou existe mesmo, essa verificação se chama unwrap.
As duas formas mais comuns de fazer unwrap são com `if let` e `guard let`.

###if let
Faz o unwrap com uma condição, se tiver algum valor dentro do opcional você consegue usá-lo, caso contrário a condição falha e você pode fazer alguma outra ação que não use o opcional.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tlhlmsgs9spr9otgesfb.png)<figcaption>Checa se existe um dado dentro de nome pra que o dado possa ser usado</figcaption>

> A partir do Swift 5.7 não é mais necessário o uso de binding(passar o valor do opcional pra uma constante) no if let


###guard let 
Faz o unwrap passando o dado existente pra uma constante(binding), caso ache nil fecha a função, loop ou condição onde foi usado.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j0hg6bplmyum17otnwrf.png)<figcaption>Checa se foi passada uma string na chamada da função, como esse dado foi passado usa ele depois do guard</figcaption>


> A maior diferença entre `if let` e `guard let` é que no guard o dado que foi checado e agora é não opcional continua usável depois do guard.

---

##Force unwrapping
Quando você tem um valor opcional mas tem certeza absoluta de que ele não é nil é possível forçar o swift a transformar ele em um tipo não opcional usando `!`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54sygqsv1mc0bce00h0t.png)<figcaption>O próprio swift gera warnings em casos mais arriscados dando alternativas, mas nem sempre isso vai acontecer então é bom usar ! com cautela</figcaption>

O uso de force unwrapping é bastante contraindicado na maioria dos casos porque você pode esquecer alguma validação e o dado chegar nil no ponto do código que força essa conversão pra não opcional, caso isso aconteça o código _crasha_ e esse é o pior cenário possível pra um app.

---

##Implicitly Unwrapped Optionals
Assim como os opcionais regulares, podem conter um dado ou serem nil, mas diferente dos regulares você não precisa fazer unwrap pra utilizá-los.

_Implicitly unwrapped optionals_ são criados adicionando uma exclamação depois do nome: `let idade: Int! = nil`

Por se comportarem como opcionais em que já foi feito o unwrap, não é necessário fazer `if let` ou `guard let` pra usá-los, mas se tentarmos usá-los e eles forem nil o código da crash.

Usamos esse tipo de opcional quando uma variável começa como nil, mas sabemos que sempre vai ter um valor dentro dela antes de precisarmos usá-la, o uso desse tipo evita que precisemos fazer `if let` toda hora, mas num geral é melhor evitar e usar opcionais regulares.

No UIKit são comumente usadas pra layout, já no SwiftUI quase não são utilizadas.

---

##Nil coalescing | Valor padrão
O operador nil coalescing faz o unwrap do opcional e retorna o valor dentro dele, mas caso esse valor seja nil ele retorna o valor que foi colocado como padrão: `?? valorPadrao`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5j11ft8d7wv2qfokm8r.png)<figcaption>Valor padrão é um Int 7</figcaption>

---

##Optional chaining
É um processo para consultar e chamar propriedades e métodos opcionais. Se o opcional contiver um valor, a chamada de propriedade/método da certo e retorna sempre um opcional, se for nil retorna nil. Várias consultas podem ser encadeadas e toda a cadeia falha se algum deles for nil.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j00r5ku0kz2v8hgx5qz.png)<figcaption>O retorno de um optional chaining sempre é um valor opcional ou nil</figcaption>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/quk9ovf5u31bfise4z11.png)<figcaption>O retorno é nil porque apesar Daken ser uma chave válida o valor(sobrenome) está vazio, assim o first retorna nil</figcaption>

---

##Failable initializer
É possível criar um init para struct ou classe que pode falhar. Caso um objeto não possa ser instanciado com os dados que foram passados, ao invés de retornar sempre uma nova instância, retorna nil. Caso os dados sejam válidos retorna uma instância opcional.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxu9s8bhzifo2d68h5av.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wa369jfe044snypwdzl6.png)<figcaption>Instância opcional criada</figcaption>

---

##Typecasting
Nos permite verificar o tipo de uma instância e mostrar ao Swift como tratá-la dentro da sua própria hierarquia, é muito útil ao trabalhar com protocolos e herança de classe.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1xuucb49mifu5rdifnf.png)