nils in type switches

May 23, 2024

Type switches

Instead of a type, a case may use the predeclared identifier nil; that case is selected when the expression in the TypeSwitchGuard is a nil interface value. There may be at most one nil case.

Straight forward, right? Here’s an example:

switch x.(type) {
  case int:
  case string:
  case nil:
}

But now here’s a question: If we assign x.(type) to a temporary variable the TypeSwitchGuard, what is its type in the nil case?

We can find out with a simple test:

var x any
var y error

switch t := x.(type) {
case nil:
	y = t
}

This code fails to compile with a telling error message:

use t (variable of type any) as error value in assignment: any does not implement error (missing method Error)

So there’s our answer: In the nil case (and as we saw yesterday, the default and any other case with multiple types), the temporary variable’s type is the same as x’s 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 .

Related Content


Temporary variables in type switches

Type switches … TypeSwitchStmt = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" . TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" . TypeCaseClause = TypeSwitchCase ":" StatementList . TypeSwitchCase = "case" TypeList | "default" . The TypeSwitchGuard may include a short variable declaration. When that form is used, the variable is declared at the end of the TypeSwitchCase in the implicit block of each clause.


Type switches conclusion

Two final items with regard to type switches, before we move on to the next topic: Type switches … The type switch guard may be preceded by a simple statement, which executes before the guard is evaluated. This is pretty straight forward. It works just like the simple statements in if statements and normal switch statements. A simple statement can be used both with or without a temporary variable. In other words, both of these are valid:


A long type switch example

We’ve been looking at type switches since last week. Today the spec shows us a large example, comparing type switches to the equivalent expressed without them. Type switches … Given an expression x of type interface{}, the following type switch: switch i := x.(type) { case nil: printString("x is nil") // type of i is type of x (interface{}) case int: printInt(i) // type of i is int case float64: printFloat64(i) // type of i is float64 case func(int) float64: printFunction(i) // type of i is func(int) float64 case bool, string: printString("type is bool or string") // type of i is type of x (interface{}) default: printString("don't know the type") // type of i is type of x (interface{}) } could be rewritten:

Get daily content like this in your inbox!

Subscribe