Quando utilizar generics?

Assim como as goroutines, uma das dúvidas que mais tenho visto quando o assunto é generics, a nova feature do Go 1.18, é quando ela deve ser utilizada.

Nesse post, baseado no post publicado em 12 de abril no blog oficial do Go (When to use generics), vou tentar passar um pouco das dicas dadas pelo Ian Lance Taylor.

Ele começa o primeiro vídeo falando sobre como escrever código Go. De forma muito simples e em tradução livre ele diz:

Escreva código, não desenhe tipos.

Esse pensamento se mostra muito útil, não só para o resto do vídeo, mas sim para toda forma de pensar sobre arquitetura de software.

Muitas vezes investimos um longo período de tempo planejando em como separar os componentes, deixar o código reutilizável e etc.. E no final, acabamos não precisando reutilizar nada ou muito pouco de toda aquela arquitetura mirabolante que criamos.

Por isso, eu particularmente, gosto de um desenvolvimento incremental. Mas isso é assunto para um outro post.

Voltando ao tópico desse post, para mim, o principal conselho sobre quando utilizar generics é:

Comece escrevendo funções e adicione generics somente quando fizer sentido, quando for útil.

Em outras palavras, precisamos deixar de pensar em generics de forma prematura. Ao invés disso, podemos deixar para pensar em adicionar generic à uma função somente quando ela precisar ser reutilizável por outro tipo de dado.

É claro que se você estiver trabalhando em uma biblioteca, pode fazer sentido já pensar em utilização genérica de uma função ou método desde o inicio. Porém, a maioria de nós escreve código para casos específicos, para softwares que nascem com finalidades bem definidas, ou seja, não precisamos pensar em reutilização até que algo realmente precise ser reutilizado.

Para ajudar um pouco mais na tomada de decisão, Ian dá 3 dicas sobre onde a utilização de generics pode ser útil.

  1. Funções que trabalhem com slices, maps e channels;
  2. Estruturas de dados(structs) de uso geral, como por exemplo, uma lista encadeada (linked list) ou árvore binária (binary tree);
  3. Quando um método for igual para qualquer tipo de dado.

Agora, além de saber quando utilizar generics, outro ponto importante é saber quando NÃO utilizar generics.

De forma bem direta, vou resumir em 3 pontos quando não devemos utilizar generics.

  1. Quando uma interface resolver o problema, como por exemplo io.Reader;
  2. Quando a implementação de um método for diferente para cada tipo;
  3. Quando as operações forem diferentes para cada tipo.

Um exemplo que ele dá sobre o terceiro item é a implementação do json.Marshal e json.Unmarshal, onde ao invés de exigir que cada tipo tenha sua própria implementação desses métodos, pelo fato do tratamento ser diferente para cada um dos tipos, utilizar reflection faz muito mais sentido do que generics.

Espero que esse pequeno guia ajude vocês.

Deixem nos comentários suas dúvidas e até a próxima!


Subscreva

Fique por dentro de tudo o que acontece no mundo Go.

Deixe uma resposta