Type Assertions & Type Switches
Type assertions
A type assertion extracts the concrete value stored inside an interface:
The two-value (safe) form never panics:
Always prefer the two-value form unless a wrong type is a programming error you want to crash on.
Type switches
A type switch tests an interface value against multiple concrete types in one construct:
Inside each case, x is already typed โ no further assertion needed.
The any type
any is an alias for interface{} (introduced in Go 1.18). Functions that accept arbitrary values use any:
Checking error types
Type assertions are the mechanism behind errors.As:
You can also use a type switch directly on errors:
Interface satisfaction check
Use a blank identifier assertion as a compile-time check that a type implements an interface:
Common pitfalls
- Asserting a nil interface panics:
var w io.Writer; w.(*os.File)โ always check for nil first fmt.Errorf("...: %w", err)wraps errors โ useerrors.Asrather than type asserting the raw error to unwrap correctly- Asserting to an interface (not a concrete type) is valid and often useful for capability checks
Knowledge Check
What is the difference between `f := w.(*os.File)` and `f, ok := w.(*os.File)`?
Inside a type switch `switch x := v.(type) { case string: ... }`, what is the type of x inside the string case?
What does `var _ io.Writer = (*MyWriter)(nil)` accomplish?