# Why Type Assertions Matter
Type assertions let you safely recover concrete values from interface variables at runtime. They are essential at API boundaries, decoding layers, and error inspection flows.
# Type Assertion Basics
Use comma-ok when the type is uncertain to avoid runtime panics.
var i interface{} = "hello"
s := i.(string) // unsafe form
s, ok := i.(string) // safe form
n, ok := i.(int) // ok=false# Type Switches for Multi-Type Logic
Prefer type switches when many candidate dynamic types are expected.
func typeInfo(v any) string {
switch x := v.(type) {
case nil:
return "nil"
case int:
return fmt.Sprintf("int(%d)", x)
case string:
return fmt.Sprintf("string(%q)", x)
default:
return fmt.Sprintf("other(%T)", x)
}
}# Error Type Inspection
Prefer errors.As over direct assertions when errors may be wrapped.
var nfe *NotFoundError
if errors.As(err, &nfe) {
fmt.Println("not found:", nfe.Name)
}# Practice Challenge
Implement Sum(values []any) float64using a type switch to accumulate only numeric values.
package main
import "fmt"
func Sum(values []any) float64 {
// TODO: sum int and float64 values only
}
func main() {
values := []any{1, 2.5, "skip", 3, true, 4.5}
fmt.Println(Sum(values))
}⚡ Key Takeaways
- Use comma-ok assertions for safety on uncertain dynamic types
- Use type switches when handling multiple type branches
- Use
errors.Asfor wrapped error chains - Avoid unsafe assertions in production boundaries