Generics en Go: para qué sirven y cómo usarlos para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿Qué son los Generics y por qué aparecieron en Go?

\n

Durante mucho tiempo, el lenguaje Go (Golang) fue uno de los pocos lenguajes modernos sin soporte para programación genérica (generics). Los desarrolladores tenían que duplicar código para diferentes tipos de datos o usar interfaces y interface{} vacíos, lo que provocaba pérdida de seguridad de tipos y la necesidad de realizar conversiones de tipos en tiempo de ejecución.

\n

Con el lanzamiento de la versión Go 1.18 (febrero de 2022), el lenguaje incorporó los tan esperados genéricos. Generics es un mecanismo que permite escribir funciones, tipos y estructuras de datos que funcionan con tipos arbitrarios, manteniendo una tipificación estricta en tiempo de compilación.

\n

En este artículo veremos:

\n
    \n
  • Para qué sirven los genéricos en Go;
  • \n
  • Cómo declarar funciones y tipos genéricos;
  • \n
  • Qué son los constraints y cómo usarlos;
  • \n
  • Ejemplos prácticos de aplicación.
  • \n
\n\n

¿Para qué sirven los Generics en Go?

\n

Antes de la llegada de los genéricos, un problema típico era: necesitas escribir una función que trabaje con slices de diferentes tipos (por ejemplo, int, string, float64).

\n

Sin genéricos tenías que escribir tres funciones separadas:

\n
func SumInts(nums []int) int {\n    total := 0\n    for _, v := range nums {\n        total += v\n    }\n    return total\n}\n\nfunc SumFloats(nums []float64) float64 {\n    total := 0.0\n    for _, v := range nums {\n        total += v\n    }\n    return total\n}\n
\n

O usar interface{} con conversión de tipos — inseguro e incómodo.

\n

Con genéricos basta con una sola función:

\n
func Sum[T int | float64](nums []T) T {\n    var total T\n    for _, v := range nums {\n        total += v\n    }\n    return total\n}\n
\n

Las ventajas son evidentes:

\n
    \n
  • Seguridad de tipos — los errores de tipo se detectan en tiempo de compilación;
  • \n
  • Reducción de duplicación de código — una función para muchos tipos;
  • \n
  • Legibilidad — el código se vuelve más conciso y claro.
  • \n
\n\n

Fundamentos de la sintaxis de Generics en Go

\n

Declaración de una función genérica

\n

La sintaxis básica usa corchetes [] para indicar los parámetros de tipo:

\n
func NombreFuncion[NombreTipo constraint](parámetros) resultado {\n    // cuerpo de la función\n}\n
\n

Ejemplo de una función simple que devuelve el valor recibido:

\n
func Identity[T any](value T) T {\n    return value\n}\n\nfunc main() {\n    fmt.Println(Identity[int](42))       // 42\n    fmt.Println(Identity[string]("Go"))  // Go\n}\n
\n

Go puede inferir el tipo automáticamente, por lo que la indicación explícita [int] no es obligatoria:

\n
fmt.Println(Identity(42))       // Go entiende que T = int\nfmt.Println(Identity("Go"))    // T = string\n
\n\n

Tipos genéricos (estructuras)

\n

Los genéricos funcionan no solo con funciones, sino también con tipos definidos por el usuario:

\n
type Stack[T any] struct {\n    elements []T\n}\n\nfunc (s *Stack[T]) Push(value T) {\n    s.elements = append(s.elements, value)\n}\n\nfunc (s *Stack[T]) Pop() (T, bool) {\n    if len(s.elements) == 0 {\n        var zero T\n        return zero, false\n    }\n    value := s.elements[len(s.elements)-1]\n    s.elements = s.elements[:len(s.elements)-1]\n    return value, true\n}\n\nfunc main() {\n    intStack := Stack[int]{}\n    intStack.Push(10)\n    intStack.Push(20)\n    val, ok := intStack.Pop()\n    fmt.Println(val, ok) // 20 true\n}\n
\n\n

Constraints: restricciones para tipos

\n

En los ejemplos anteriores usamos any — un constraint incorporado que significa "cualquier tipo". Sin embargo, a menudo es necesario imponer restricciones: por ejemplo, que el tipo soporte comparación u operaciones aritméticas.

\n

Incorporados

Blogs

Book Recommendations