>_
GolangStepByStep
Intern

Type Assertions

Extract concrete values from interfaces with type assertions and switches

# 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.As for wrapped error chains
  • Avoid unsafe assertions in production boundaries
practice & review