Vamos dissecar as diferenças entre os genéricos e o tipo Any em Swift

Boudhayan Biswas Blocked Unblock Seguir Seguindo 9 de janeiro Foto de Aleks Dorohovich em Unsplash

O Swift é uma das linguagens mais seguras de tipos atualmente. ???

Ohhh espere !! O que significa se uma linguagem é segura para o tipo? ?

Uma linguagem de tipos seguros sempre garante que uma operação funcione com o tipo certo de dados disponíveis naquele ponto.?

Se uma linguagem tiver a capacidade de declarar diferentes tipos de dados (por exemplo, Int, Float, String, Array, Dictionary) e também tiver a capacidade de garantir que uma variável declarada com um determinado tipo de dados nunca contenha um tipo diferente de dados, então é chamado de uma linguagem de tipo seguro.

Em linguagens seguras de tipos, a verificação de tipos é sempre feita. Isso pode acontecer em tempo de compilação ou tempo de execução dependendo do idioma.?

Agora, o que são genéricos no Swift?

Os genéricos são seguros e nos ajudam a escrever funções e tipos flexíveis e reutilizáveis. Usando Generics, podemos escrever código que funciona para todos os tipos de dados. Como o Swift é uma linguagem de digitação segura, sem quebrar isso, podemos escrever códigos genéricos que podem evitar a duplicação de código.

Vamos dar um exemplo simples: uma matriz é uma coleção ordenada que pode conter o mesmo tipo de dados. É por isso que na definição de um Array, podemos ver que é preciso um tipo genérico de Elemento . Por isso, um array se torna um tipo genérico de coleção .

Está bem. Legal. Então qual é o tipo Any em Swift? ???

O Swift também suporta o tipo Any. Como o nome indica, ele pode representar uma instância de qualquer tipo como struct, class, enum e tipo de função.

O mesmo acontece com o código Objective C e o Swift com o mesmo? ?

No Swift 3, o tipo de identificação do Objective C mapeia para qualquer tipo de Swift. Isso melhora a compatibilidade do Swift e do Objective C.

Mas como e por quê?

No Swift 2, o ID do Objective C foi mapeado para qualquer objeto do Swift. Isso funcionou bem na maioria dos casos, mas às vezes resultou em comportamento inesperado. Um dos principais conceitos do Swift são os tipos de valor, e esse mapeamento não estava fazendo a devida justiça a esse conceito.

O Swift é apenas uma nova linguagem para o desenvolvimento do iOS, e o Objective C existe há anos. Então, é claro, a maioria dos projetos foi desenvolvida apenas no Objetivo C. Agora, a fim de converter um projeto Objective em um projeto Swift, veio a exigência de que deveria ser possível conectar qualquer tipo Swift a qualquer objeto Objective C.

Mas isso não foi um problema para classes Swift e tipos de valor Swift como Int, String, Float, porque eles já têm seus equivalentes em Objective C. O problema surgiu para os tipos de valor Swift que não tinham nenhuma contraparte do Objective C.

Então, para corrigir isso, o tipo de ID do Objective C foi mapeado no tipo Swift Any.???

Definições suficientes ?. Agora vamos ao tópico principal. Pelos pontos acima, parece que o Generics e o Any são os mesmos. Mas eles são realmente ??

Em um nível alto, Any pode ser semelhante a Generics. Mas vamos tentar encontrar algumas diferenças ???

Nós todos sabemos o que é uma pilha em estruturas de dados, certo? Uma pilha é uma estrutura de dados linear básica em que a inserção e a exclusão de itens ocorrem apenas em uma extremidade.

Agora vamos implementar a estrutura Stack no Swift. Primeiro, vamos implementar usando Generics e depois com o tipo Any.

Implementação de pilha usando genéricos:

A implementação da pilha acima está usando genéricos. A estrutura usa um tipo genérico de item Elemento e implementa uma pilha usando esse item. Agora vamos fazer alguma operação com o Generic Stack:

Ele declara uma pilha genérica que pode conter um tipo inteiro de elemento. Estamos empurrando o elemento inteiro para a pilha. Até este ponto, tudo funciona muito bem.

Mas e se eu quiser empurrar um elemento flutuante para cima do genericStack?

?? Oops! Erro de compilação! ??

Implementação de pilha usando o tipo Any:

Nesta implementação de pilha, a matriz de itens pode conter qualquer tipo de elemento. Não estamos especificando sobre qual será o tipo de dados exato do elemento da matriz de itens na definição. Agora vamos fazer as mesmas operações básicas nesta pilha:

Sem problemas, certo? Tudo está funcionando bem aqui também. Inicialmente, declaramos uma pilha e inserimos dois elementos inteiros nela. Quando chamamos o método show () , ele imprime a matriz exata [3, 4].

Agora vamos empurrar um valor flutuante para ele.??

?? sem erro! Tudo funciona bem! ??

Então, o que está acontecendo nos bastidores? Por que não estamos recebendo nenhum erro? ? ??

Generics basicamente diz ao compilador que:

Eu declarei um tipo genérico e vou lhe dar um tipo exato depois. Eu quero que você aplique esse tipo em todos os lugares que eu especificar.

O tipo Any basicamente diz ao compilador:

Não se preocupe com essa variável, não é necessário aplicar nenhum tipo aqui, deixe-me fazer o que eu quiser fazer.

Generics pode ser usado para definir funções flexíveis, mas os tipos de argumentos ainda são verificados pelo compilador. Qualquer tipo pode ser usado para desviar do sistema de tipos do Swift.

Na declaração de pilha genérica , estamos dizendo ao compilador que a pilha deve ter apenas o tipo inteiro. Então, quando estamos tentando inserir um tipo de elemento flutuante, significa que estamos quebrando essa promessa. Por isso, está lançando um erro de tempo de compilação. Ele sempre espera que o elemento seja um tipo inteiro.

Mas para o Any Stack , não estamos obtendo nenhum tempo de compilação ou erro de execução. Mesmo se chamarmos o método show () , ele imprime a pilha como [3, 4, 5.0], o que significa que a pilha armazena valores inteiros e flutuantes. Portanto, em qualquer pilha, não há restrição de tipo, podemos inserir qualquer tipo de valor nela (mas há possibilidades de exceções de tempo de execução).

Conclusão

Portanto, se usarmos o Generics, poderemos escrever funções, estruturas, classes e protocolos flexíveis sem comprometer a segurança do tipo do Swift. Mas se usarmos o tipo Any, então somos do nosso próprio patrão, podemos fazer quase tudo que quisermos.

??? Elogios !!! Obrigado pela leitura !! ???