Generics in Go were added about a year back in Go 1.18. In my experience they are great and they fix one of the biggest roadblocks in terms of writing reusable code in Go. I’ll illustrate that with an example.

First, do ensure that you have at least Go 1.18

$ go version
go version go1.19.1 darwin/amd64

Let’s consider a simple case of implementing a Map function in Go that maps an array (well, a slice) to another array (again, actually, a slice).

First, let’s start with a non-generic implementation

package main

import (
  "fmt"
)

func Map(input []int, mapFunc func(int)int) []int {
  output := make([]int, 0, len(input))
  for _, val := range input {
    output = append(output, mapFunc(val))
  }
  return output
}

func main() {
  input := []int {1,2,3}
  squared := func(x int) int {
    return x * x
  }
  output := Map(input, squared)
  fmt.Printf("%+v\n", output)
}

And now let’s generalize the Map function, notice that, in most cases, the caller wouldn’t change at all.

// A is the input type
// B is the output type
func Map[A any,B any](input []A, mapFunc func(A)B) []B {
  output := make([]B, 0, len(input))
  for _, val := range input {
    output = append(output, mapFunc(val))
  }
  return output
}