Type Switches
switch v := iface.(type) {
case Type1:
// v is Type1
case Type2:
// v is Type2
default:
// v has interface type
}
Basic Type Switch
A type switch uses the special syntax i.(type) inside a switch statement to branch based on the interface value's actual concrete type, running the matching case's code.
Example: Basic Type Switch
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function describe
func describe(i interface{}) {
// Choose a branch based on the value of v := i.(type
switch v := i.(type) {
case int:
fmt.Println("int:", v*2)
case string:
fmt.Println("string:", v+"!")
// default runs when no case matches
default:
fmt.Println("unknown type")
}
}
// main is where the program starts running
func main() {
describe(21)
describe("hi")
describe(3.14)
}
Login to try C/C++/Java/PHP code in the editor
Grouping Multiple Types in One Case
A single case in a type switch can list several types separated by commas, useful when multiple types should be handled identically -- though inside that combined case, v keeps the original interface type rather than a specific one.
Example: Grouping Multiple Types in One Case
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function classify
func classify(i interface{}) string {
// Choose a branch based on the value of i.(type
switch i.(type) {
case int, int64, float64:
return "numeric"
case string:
return "text"
// default runs when no case matches
default:
return "other"
}
}
// main is where the program starts running
func main() {
// Print the values followed by a newline
fmt.Println(classify(5))
// Print the values followed by a newline
fmt.Println(classify("hi"))
fmt.Println(classify(true))
}
Login to try C/C++/Java/PHP code in the editor
Handling the nil Case
A type switch can include a 'case nil' to explicitly handle an interface value that holds no concrete type at all, which is worth doing separately since a nil interface behaves differently from a nil pointer stored inside a non-nil interface.
Example: Handling the nil Case
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define the function report
func report(i interface{}) {
// Choose a branch based on the value of i.(type
switch i.(type) {
case nil:
fmt.Println("no value provided")
case int:
fmt.Println("got an int")
// default runs when no case matches
default:
fmt.Println("got something else")
}
}
// main is where the program starts running
func main() {
report(nil)
report(7)
}
Login to try C/C++/Java/PHP code in the editor
- Forgetting the special switch v := i.(type) syntax only works directly in a switch statement, not as a standalone expression.
- Not handling the default case, silently ignoring types you didn't anticipate.
- Reusing the same variable name shadowed per case and being confused about its type in each branch (it's actually correctly re-typed per case, this trips up newcomers).
- A type switch, 'switch v := i.(type) { }', branches based on the concrete type stored in an interface value.
- Each case names a concrete type, and inside that case, the variable has that specific type.
- A default case catches any type not explicitly listed.
- Type switches are the idiomatic way to handle several possible concrete types held in one interface value.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: