Trabalhando com generics

Se você está no mundo Go a algum tempo, com certeza já ouviu falar desse carinha ai. Para aqueles que estão chegando agora, generics é uma das features mais pedidas/aguardadas desde que a linguagem foi liberada para o mundo.

Como já falamos em outros posts, Go é uma linguagem de tipagem forte, ou seja, sempre precisamos declarar o tipo da variável, parâmetros de uma função e seus retornos. Isso acaba fazendo com que, em algumas ocasiões, seja necessário duplicar nosso código só para que ele atenda dois tipos diferentes de dados.

Um exemplo básico desse problema seria uma função que soma uma lista de valores, onde sem generics, caso fossemos somar int64 e float64, seria necessário criar duas funções basicamente iguais, só mudando o tipo de dado do parâmetro e do retorno.

Com generics isso muda completamente, já que conseguimos escrever uma só função para realizar essa tarefa de somar uma lista de valores.

Para que o exemplo funcione, pelo menos enquanto a versão 1.18 do go não é liberada, precisamos instalar a versão 1.18 beta 1. Não se preocupe, pois é possível ter várias versões funcionando em paralelo.

Para instalar a versão 1.18 beta 1 siga os seguintes passos:

  1. Execute com comando go install golang.org/dl/[email protected] para instalar a versão 1.18 beta 1 do go
  2. Faça download de updates com o comando go1.18beta1 download
  3. Por último, faça um go1.18beta1 version para garantir que a versão foi instalada corretamente.

Agora que já temos a versão 1.18 beta 1 na máquina, vamos escrever uma função para somar uma lista de valores do tipo int64 ou float64 usando generics.

func Sum[V int64 | float64](m []V) V {
    var s V
    for _, v := range m {
        s += v
    }

    return s
}

Como podemos ver, quando queremos usar generics, tudo que precisamos fazer é declarar as representações genéricas dentro de colchetes.

No nosso caso, criamos uma representação genérica para os tipos int64 e float64 com o nome de V.

Com essa declaração feita, agora é só usar o V como se fosse um tipo de dados.

Agora vamos escrever uma função main para testar nossa função com generics.

package main

import "fmt"

func Sum[V int64 | float64](m []V) V {
    var s V
    for _, v := range m {
        s += v
    }

    return s
}

func main() {
    ints := []int64{1,2,3,4,5,6}
    floats := []float64{12.3, 13.5, 10.7, 11.42}

    fmt.Println("soma int64:", Sum[int64](ints))
    fmt.Println("soma float64:", Sum[float64](floats))
}

Um outro detalhe para funções que utilizam generics, é que na chamada da função utilizamos colchetes para dizer qual o tipo de dado que estamos utilizando como o tipo genérico.

Caso alguém tente passar um tipo diferente dos que foram declarados na função, um erro será retornado.

string does not implement int64|float64

Para testar nossa implementação, execute o comando go1.18beta1 run main.go.

Deixem suas dúvidas nos comentários.

Até a próxima!


Subscreva

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

2 comentários sobre “Trabalhando com generics

Deixe uma resposta