Go

In a type switch, what is the type of the bound variable when a case lists several types, and how does case nil behave?

Question 10HardGo 1.22 to 1.25
func describe(x any) string {
	switch v := x.(type) {
	case nil:
		return "nil interface"
	case int, int64:
		// v has type any here, NOT int
		return fmt.Sprintf("integer %v", v)
	case string:
		return "string of len " + strconv.Itoa(len(v)) // v is a string
	case error:
		return "error: " + v.Error()
	case fmt.Stringer:
		return "stringer: " + v.String()
	default:
		return fmt.Sprintf("other %T", v)
	}
}

Rules:

  • If a case lists exactly one type, v has that type.
  • If a case lists several types, or in default, v keeps the type of the switch expression (here any). So v + 1 would not compile in case int, int64.
  • case nil matches only when the interface itself is nil. An interface that holds a (*T)(nil) does not match it.
  • Cases are checked in order. Put more specific interfaces (such as error) before broader ones. A type that implements both error and Stringer goes to whichever case comes first.
  • fallthrough is not allowed in a type switch.

More on Language Fundamentals & Types

All 39 Language Fundamentals & Types questions