Métodos genéricos en Go 1.27: la limitación que duró desde 2022

Fuentes: Generic Methods in Go 1.27

Go 1.27 elimina una antigua restricción del lenguaje: los métodos ya pueden declarar sus propios parámetros de tipo sin necesidad de añadirlos al struct receptor. Hasta ahora, quien quisiera implementar, por ejemplo, un método Map que transformara un nodo genérico Node[T] en otro de tipo U estaba obligado a incluir U en la definición del propio struct, aunque el resto de métodos no lo usaran, o bien a recurrir a una función a nivel de paquete. La nueva sintaxis permite declarar U únicamente en el método: func (n *Node[T]) MapU any Node[U] { ... }.

La limitación tenía una razón técnica profunda. El compilador de Go implementa los genéricos principalmente mediante monomorfización: genera una copia del código genérico por cada tipo concreto con el que se instancia. El sistema de interfaces, en cambio, funciona en tiempo de ejecución mediante dynamic dispatch. Declarar métodos genéricos dentro de interfaces obligaría a un compilador JIT o a generar copias para todos los tipos posibles, con el consiguiente inflado del binario. Por eso el equipo de Go decidió separar los métodos genéricos de las interfaces: Go 1.27 permite métodos genéricos en tipos concretos, pero no en interfaces, y la propuesta de añadirlos a interfaces sigue siendo un asunto sin resolver.

El cambio se percibe como un avance largamente esperado desde que Go 1.18 introdujo genéricos en 2022, y acerca al lenguaje a una expresividad más idiomática sin sacrificar el modelo de compilación.