How to Use Generics in Go Starting From v1.17

Using a flag that appears to have been brought to light with v1.17


Got comments?

As we know, Go 1.18 is expected to bring generic type parameters to the Go language later this year or early next one. For those unable to wait until then, there is a special version of the Go Playground, as well as a (rather tricky) way to play with them locally, for those willing to build Go from source.

All that until today's release of Go 1.17:

Among the other new features, there is a special flag -gcflags=-G=3 which, when used, will run and build code that uses type parameters. I first saw it mentioned here, but other than this source, I found little other public information. Probably, for a good reason.

Anyway, I am happy to confirm that it works! That is, with one tiny caveat. I used the code from the Go 2 playground:

package main

import (
	"fmt"
)

// The playground now uses square brackets for type parameters. Otherwise,
// the syntax of type parameter lists matches the one of regular parameter
// lists except that all type parameters must have a name, and the type
// parameter list cannot be empty. The predeclared identifier "any" may be
// used in the position of a type parameter constraint (and only there);
// it indicates that there are no constraints.

func Print[T any](s []T) {
	for _, v := range s {
		fmt.Print(v)
	}
}

func main() {
	Print([]string{"Hello, ", "playground\n"})
}

when I tried to run it using the aforementioned flag, I got the following error:

$ go1.17 run -gcflags=-G=3  cmd/generics/main.go

# command-line-arguments
cmd/generics/main.go:14:6: internal compiler error: Cannot export a generic function (yet): Print

No problem, lets unexport Printfor now, by renaming it to print.

Runnung the same command now executes absolutely fine!

$ go1.17 run -gcflags=-G=3  cmd/generics/main.go

Hello, playground

How useful is all that?

It's a step forward, for sure. At least, you want have to compile Go form the source code if you wanted to play with type params. However, the Go compiler is only half of the game. The other part is the tooling. From my limited amount of testing, only `run` and `build` seem to support this flag. Other than that, both my attempts to run formatting and testing failed with no success.

I am expecting to see more tooling support as we move closer to Go 1.18