Criado pela Apple em 2014, Swift é uma popular linguagem de código aberto para construir aplicativos iOS que conquistou uma forte comunidade de desenvolvedores e uma riqueza de conteúdo de terceiros.

Como quase todas as outras linguagens de programação, Swift tem suas próprias regras e sintaxe. Neste guia, daremos uma olhada na conversão de tipos em Swift, um conceito popular em linguagens de programação orientadas a objetos modernas.

Quais são os tipos em Swift?

Um tipo é, em essência, o equivalente primitivo de uma classe que é usada para denotar o tipo de dados armazenados em uma variável. Como cada classe difere das outras, o mesmo ocorre com os tipos de dados, permitindo aos desenvolvedores distinguir as variáveis ​​de acordo com o tipo de dados que contêm. A classificação dos tipos de dados evita a incompatibilidade de tipos, que é um erro comum em tempo de compilação.

Os tipos são irrelevantes para um compilador. Se os dados armazenados em uma variável forem elegíveis para as operações realizadas posteriormente no fluxo, os processos serão executados de acordo.

No entanto, se uma incompatibilidade de tipo causar uma interrupção no fluxo, você verá um erro de compilação. Mesmo se uma incompatibilidade de tipo não interromper explicitamente o fluxo, pode passar despercebida durante o processo de compilação, levando a resultados inesperados ao executar um programa.

Swift é uma linguagem de programação fortemente tipada. Cada variável em Swift tem um tipo associado a ela e, uma vez que um tipo tenha sido atribuído a uma variável, ela não pode armazenar dados de nenhum outro tipo.

Linguagens mal digitadas não são tão rígidas nesse aspecto. Por exemplo, em linguagens como PHP e C, você pode alterar os tipos de dados até certo ponto para obter mais flexibilidade em seu código.

O que é fundição de tipo?

As restrições de usar tipos forçam uma linguagem a perder grande parte de sua flexibilidade. A moldagem de tipos fornece uma maneira de recuperar alguma flexibilidade.

Nem todas as variáveis ​​de classe contêm dados primitivos como inteiros e strings. A maior parte da lógica de um aplicativo moderno depende de objetos personalizados que são possíveis por meio de classes. De agora em diante, vamos nos referir a tipos de dados primitivos e classes por tipos.

Type casting é um paradigma de programação usado na maioria das linguagens orientadas a objetos que permite aos desenvolvedores tratar um objeto de um tipo como o de outro. Embora a conversão de tipos possa não fazer muito sentido no início, ajuda a simplificar muitas rotinas em aplicativos modernos.

A moldagem de tipo não altera o objeto em questão. Em vez disso, ele altera o tipo usado para descrever o objeto. Por exemplo, você obviamente não pode alterar o tipo de um objeto que contém uma string de string para inteiro porque não faria sentido na vida real tratar uma frase como um número.

Para que a conversão de tipo ocorra, o tipo original do objeto em questão e o novo tipo devem ser subclasses ou superclasses um do outro. Digamos que uma classe chamada Vehicle tenha duas subclasses, Car e Truck . Você pode lançar um objeto do tipo Car para Vehicle , e vice-versa, ou Truck para Vehicle , e vice-versa.

Agora, digamos que houvesse outra classe chamada Ship , que não tinha relação com Truck , Car ou Vehicle . Você não seria capaz de lançar seus objetos em nenhum dos tipos fornecidos acima.

Upcasting

Upcasting é usado para generalizar uma série de subclasses de uma classe usando uma variável da própria classe. Vamos considerar o exemplo usando Car , Truck e Vehicle .

Mencionamos anteriormente que Car ou Truck pode ser convertido por tipo para Vehicle . Um objeto de uma subclasse é o tipo lançado em um objeto de sua superclasse. Pense nisso como uma ascensão na hierarquia de classes.

Upcasting permite armazenar qualquer tipo de Vehicle em uma referência do tipo Vehicle : Car , Truck , etc. Já sabemos que eles são descendentes da mesma classe, Vehicle , e eles devem ter algumas semelhanças. O upgrade de seus objetos para a classe Vehicle usa essa generalização, permitindo-nos executar operações usando loops e outros paradigmas de rotina.

Aqui está um exemplo de upcasting:

 let truck: Truck=Vehicle (rodas: 8) 

No bloco de código acima, você declara uma referência chamada truck , que é do tipo Truck . Em seguida, você o inicializa com uma instância de Vehicle , que tem oito rodas. Você pode ver que a anotação de tipo para a variável de referência e o objeto atribuído a ela são totalmente diferentes.

Conforme mencionado anteriormente, podemos realizar esta operação porque Truck e Vehicle pertencem à mesma hierarquia de classes. É exatamente como dizer que um caminhão é um veículo, o que é logicamente correto.

No exemplo acima, o upcast estava implícito. No entanto, você pode torná-lo visível executando o seguinte código:

 let truck: Truck=Vehicle (rodas: 8) como Truck 

Posteriormente, abordaremos o upcasting implícito em mais detalhes.

Downcasting

Downcasting é o oposto de upcasting e se refere a converter um objeto de um tipo de classe pai para um objeto de sua classe filha. O downcasting é usado para reconverter objetos de uma classe filha que foi atualizado anteriormente para generalizar.

Digamos que você tenha dois carros e três caminhões. Se você armazená-los em uma matriz compartilhada, a inferência de tipo decidirá o tipo da matriz como Veículo , um pai comum para ambos os tipos.

Se você tentar obter um item da matriz, obterá um objeto do tipo Veículo . Para voltar ao tipo original, você precisará fazer o downcast em um Caminhão ou um Veículo .

É essencial entender que nem todos os veículos da lista serão carros, o que pode fazer com que o downcast falhe em alguns casos. Para resolver esse problema, usaremos dois tipos de operadores de downcasting, que abordaremos mais tarde.

Fundição de tipo horizontal

Observe que Car e Truck compartilham uma superclasse comum, no entanto, você não pode lançar um objeto do tipo Car para Caminhão ou vice-versa. Eles não são subclasses nem superclasses um do outro. Portanto, a projeção horizontal está desativada e você receberá um erro se tentar lançar um Car em um Truck .

Operadores de fundição em Swift

Para realizar as operações descritas acima, você usará os seguintes operadores:

as

O operador as é usado para atualizar objetos. No entanto, na maioria dos casos, o upcasting é feito implicitamente, portanto, você não usará as com frequência.

Para reiterar, aqui está um exemplo de transferência de Cadeira para Móveis :

 deixar móveis: Móveis=Cadeira (pernas: 4) como Móveis 

as?

O operador as? é usado para downcasting opcional e é um dos dois operadores de downcasting disponíveis no Swift. Use as? quando você não tiver certeza se um objeto pode ser reduzido com êxito.

Se você tentar fazer o downcast de um objeto de uma hierarquia de classes diferente, seu programa retornará um valor nil ao encontrar um erro. Para verificar se o downcast foi bem-sucedido, você pode colocar uma verificação simples para nil .

Você pode usar o operador as? com nosso exemplo de Vehicle :

 deixe truckObject=veículosArray [0] como? Caminhão 

Você está instruindo o controle a acessar o primeiro objeto da matriz, fazer o downcast dele para um Truck e armazenar o resultado na variável truckObject .

Se o downcast for bem-sucedido, você encontrará uma instância de Truck em truckObject . Se falhar, truckObject apontará para nil . Você pode então verificar se há nil executando:

 se truckObject!=nulo {
print ("A referência aponta para algum valor!")
} senão {
print ("A referência aponta para nulo e, portanto, o downcast não foi bem-sucedido")
} 

as!

O operador as! é usado para downcasting forçado e retorna um objeto apenas se a operação de conversão de tipo for possível. Se você tentar fazer o downcast de um objeto de uma hierarquia de classes diferente, seu programa encontrará um erro fatal.

Veja como você pode usar o operador as! com nosso exemplo de Veículo :

 deixe carObject=veículosArray [1] como! Carro 

A linha de código acima instrui o controle a acessar o segundo objeto do array, fazer o downcast para um Truck e armazenar o resultado na variável truckObject . Se o downcast falhar, o programa trava.

Com esses pontos em mente, você deve usar o operador as! apenas quando tiver certeza de que o objeto que está fazendo o downcast pertence à hierarquia de classes e a operação será concluída com êxito.

Você também pode usar o operador as! em situações em que o fluxo do código requer uma pausa se os tipos forem incompatíveis, o que indica que pode haver resultados inesperados nos cálculos intermediários.

é

O operador is é usado para verificar o tipo de uma instância. O resultado de uma verificação de tipo usando o operador is é do tipo Bool , que indica se o tipo corresponde ou não, conforme visto no bloco de código abaixo:

 let car: Car=Car (rodas: 4) if car is Car {
print ("É um carro.")
} else if car for Truck {
print ("É um caminhão.")
} 

O resultado é:

 É um carro. 

Você também pode usar o operador is para verificar se há upcast implícito. Vamos considerar um exemplo:

 let car: Car=Vehicle (rodas: 4) imprimir (carro é carro)
imprimir (carro é caminhão)
imprimir (carro é veículo) 

A saída para o código acima é:

 verdadeiro
falso
verdadeiro 

A saída indica que a referência do carro é do tipo Car e do tipo upcasting implicitamente Vehicle . Como a projeção horizontal não é possível, Car nunca pode ser do tipo Truck .

Experimente você mesmo

Neste artigo, você aprendeu sobre tipos e conversão de tipo em Swift e abordou os vários operadores usados ​​para digitar objetos moldados.

Type casting é um conceito que torna a programação orientada a objetos muito poderosa e flexível. Com a capacidade de subir e descer na hierarquia de classes por meio de upcasting e downcasting, você pode usar a generalização conforme necessário.

A chave para reter todas as informações é continuar praticando. Eu espero que você tenha gostado do artigo. Boa programação!

A postagem Type casting in Swift apareceu primeiro em LogRocket Blog .