Go is over ten years old language but generics (type parameters) are introduced just in the March this year. Hence, still lot of developers avoid using them or have certain problems once decided to give it a try. One of the common problems is how to check the concrete type of a generic parameter, specially of non constrained parameters. So, if you try to do the following, it won’t work:

1
2
3
4
5
6
7
8
func example[T any](s T) {
	switch s.(type) {
	case string:
		// do something
	default:
		// do something else.
	}
}

Compiler will just throw an error cannot use type switch on type parameter value s (variable of type T constrained by any). What the heck does this mean? Simply, Go can find out the concrete type just for a variable of type any (alias for interface{}) and our variable in this example is actually of generic type T with constraint any, but this is not the same. The trick how to fix this is simple, you just have to convert the s variable to type any:

1
2
3
4
5
6
7
8
func example[T any](s T) {
	switch any(s).(type) {
	case string:
		// do something
	default:
		// do something else.
	}
}

And voila, it compiles and works as expected. Besides switching on type, you can also assure the type of a variable using similar approach:

1
2
3
4
5
func example[T any](s T) {
	if s, ok := any(s).(string); ok {
		fmt.Printf("we got string %s\n", s)
	}
}

Here is the Go Playground link if you want to practice this yourself.