Se introducen métodos genéricos en Go 1.27

Se introducen métodos genéricos en Go 1.27

En marzo escribí sobre la propuesta de métodos genéricos - https://t.me/junsenior/332, y hace 2 semanas con el lanzamiento de Go 1.27 fue liberada.

¿Qué cambia esto?: antes, ningún método podía tener parámetros genéricos, por ejemplo:

type SomeStruct struct {
 intField int
}
 
// syntax error
func (s SomeStruct) Map[U any](mapFunc func(int) U) U {
 return mapFunc(s.intField)
}

En lugar de métodos, si se necesitaba añadir un método con tipo genérico a un tipo, se creaban funciones normales:

func Map[U any](s SomeStruct, mapFunc func (int) U) U {
 return mapFunc(s.intField)
}

Ahora, el ejemplo anterior es completamente válido para cualquier método, no solo para estructuras. Y ahora estos métodos nos desbloquearon las cadenas de llamadas:

type Box[T any] struct {
    val T
}
 
func (b Box[T]) Map[U any](mapFunc func(T) U) Box[U] {
    return Box[U]{val: mapFunc(b.val)}
}
 
b := Box[int]{val: 42}
 
res := b.Map(strconv.Itoa).
  Map(func(s string) string { 
      return "user-" + s 
   }).
  Map(strings.ToUpper)
 
// USER-42
fmt.Printf("%#v\n", res)   

En el paquete math/rand/v2 ya se puede encontrar un ejemplo:

func (r *Rand) N[Int intType](n Int) Int {
    if n <= 0 {
        panic("invalid argument to N")
    }
 
    return Int(r.uint64n(uint64(n)))
}

Y en 1.26 en su lugar en el paquete había una función normal:

func N[Int intType](n Int) Int {
 if n <= 0 {
  panic("invalid argument to N")
 }
 return Int(globalRand.uint64n(uint64(n)))
}

Como recordamos, esta propuesta encendió bastante a la comunidad: tanto en los comentarios en GitHub como en los hilos en Reddit, pero sin embargo, llegó a buen puerto. De la negación llegué a la conclusión de que los genéricos, en general, hacen el código más conveniente si se aplican correctamente - he visto varios proyectos donde encajaban muy bien. Añadirles métodos, ya que los genéricos han estado en el lenguaje durante muchos años, es la decisión correcta. O no debieron haber traído los genéricos en absoluto, o si los trajeron, deberían mejorarlos.

En general, el lanzamiento 1.27 resultó interesante. Además de los métodos genéricos, en Go ahora uuid está implementado dentro de la stdlib, trajeron encoding/json/v2 - ahora el unmarshalling funciona mucho más rápido, y muchas otras novedades. Aquí se puede ver de manera clara e interactiva esta y otras actualizaciones: https://golang.guide/go-1-27/

Y cuando casi todo el código lo escribe la IA, es importante seguir y entender qué está pasando en el lenguaje y en las herramientas con las que trabajamos: como mínimo, en una entrevista la IA no siempre tendrá tiempo de responder, y como máximo, el código necesita ser revisado y entendido, de lo contrario, cualquier proyecto rápidamente se convertirá en un caos incontrolable 🏁