Go Type Parameters Proposal is expected to be implemented with Go 1.18 early 2022.

The Very high level overview section contains a nice overview of what to expect.

If you have seen generics in other languages perhaps the most curious differences (other than using square brackets), are union types:

type SignedIntegers interface {
	int | int8 | int16 | int32 | int64

Similar in syntax to scala3/dotty union types, although in Go is only allowed in constraints. The type set of this union element is the set {int, int8, int16, int32, int64}.

Another interesting difference is the Approximation Constraint, written as ~T. The type set of ~T is the set of all types whose underlying type is T.

Testing the waters

A map function can be written as:

package main

import (

func mapFunc[A any, B any, F func(A) B, S ~[]A](f F, a S) []B {
	if a == nil {
		return nil

	res := make([]B, 0, len(a))
	for _, e := range a {
		res = append(res, f(e))

	return res

func main() {
	type User struct {
		ID   int
		Name string

	usernames := mapFunc(func(u User) string { return u.Name },
				ID:   1,
				Name: "Foo",
				ID:   2,
				Name: "Bar",

Go can infer types, allowing us to omit them, which helps readability.


So far few new packages have been added around generics:

Seems like authors are cautious around what to add. One would expect to see the usual suspects map, filter and reduce and a collections package, perhaps something the community will fill in.

Final Thoughts

Generics is going to remove a lot of code duplication at the cost of increased cognitive load parsing function signatures.

I am curious to see:

  • If some patterns will emerge around naming types

  • How to define constraints, eg for F:

    • func mapFunc[A any, B any, F func(A) B, S ~[]A](f F, a S) []B
    • func mapFunc[A any, B any, S ~[]A](f func(A) B, a S) []B

Perhaps something go fmt could “fix”.