Métodos genéricos introduzidos no Go 1.27

Métodos genéricos introduzidos no Go 1.27

Em março, escrevi sobre a proposta com métodos genéricos - https://t.me/junsenior/332, e há 2 semanas, com o lançamento do Go 1.27, ela foi liberada.

O que isso muda: antes, qualquer método não podia ter parâmetros genéricos, por exemplo:

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

Em vez de métodos, se era necessário adicionar um método com tipo genérico a um tipo, eram criadas funções comuns:

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

Agora, o exemplo acima é totalmente válido para quaisquer métodos, não apenas para estruturas. E agora esses métodos nos desbloquearam cadeias de chamadas:

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)   

No pacote math/rand/v2 já é possível encontrar um exemplo:

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

E no 1.26, em vez disso, no pacote havia uma função comum:

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

Como lembramos, essa proposta causou bastante discussão na comunidade: tanto nos comentários no GitHub quanto nos tópicos no Reddit, mas mesmo assim - ela foi implementada. Do ceticismo, cheguei à conclusão de que os genéricos, globalmente, tornam o código mais conveniente, se aplicados corretamente - vi vários projetos onde eles se encaixaram muito bem. Adicionar métodos a eles, já que os próprios genéricos estão no idioma há muitos anos, é a decisão certa. Ou não deveriam ter introduzido genéricos, ou, se introduzidos, deveriam ser aprimorados.

No geral, o lançamento 1.27 foi interessante. Além dos métodos genéricos, agora o Go tem uuid implementado dentro da stdlib, introduziram encoding/json/v2 - agora o unmarshalling funciona muito mais rápido, e há muito mais novidades. Aqui você pode ver de forma clara e interativa essas e outras atualizações: https://golang.guide/go-1-27/

E quando quase todo o código é escrito por IA - é importante acompanhar e entender o que está acontecendo na linguagem e nas ferramentas com as quais trabalhamos: no mínimo - em uma entrevista, a IA nem sempre terá tempo para responder, e no máximo - o código precisa ser revisado e compreendido, caso contrário, qualquer projeto rapidamente se tornará um "neuroslop" insustentável 🏁