Type switches with generics

May 27, 2024

More live coding today! Join me! And bring your questions.


Type switches

A type parameter or a generic type may be used as a type in a case. If upon instantiation that type turns out to duplicate another entry in the switch, the first matching case is chosen.

func f[P any](x any) int {
	switch x.(type) {
	case P:
		return 0
	case string:
		return 1
	case []P:
		return 2
	case []byte:
		return 3
	default:
		return 4
	}
}

var v1 = f[string]("foo")   // v1 == 0
var v2 = f[byte]([]byte{})  // v2 == 2

The example included is nice, because it shows two examples of the type parameter P being used: Both the first case (case P) and third (case []P) use the type parameter.

But notice that this is distinctly different from using a type switch to determine the underlying type of a type parameter. We already talked about this briefly, but I think a recap is in order. Consider the following function signature:

func f[P int | float64](x P) int {

We could use the above construct, and include P in a type switch case:

switch y := x.(type) {
case P:

However, here y is of type P, not specifically of type int or float64. If you want to determine which underlying type P has, we need to use a different trick:

switch y := any(x).(type) {
case int:
	/* y is of type int */
case float64:
	/* y is of type float64 */
}

The trick is to convert x (of type P) to an empty interface (that’s what any(x)) does, then we can pass that value to a type switch (or type conversion), to get at the underlying type.

Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Get daily content like this in your inbox!

Subscribe