🗓️ 02112024 2300
📎
Core Concept: Type assertions check and convert interface values to specific types at runtime.
Why It Matters
Work safely with empty interfaces. Enable optional behavior patterns. Required for reflection-like operations.
When to Use
✅ Use when:
- Working with interface
 - Optional interfaces
 - Type unknown at compile time
 
❌ Avoid when:
- You control the type
 - Can use proper interfaces
 
Real Example
Optional validation pattern:
func DecodeAndValidate(r *http.Request, v interface{}) error {
    json.NewDecoder(r.Body).Decode(v)
    
    if validator, ok := v.(Validator); ok {
        return validator.Validate()  // Call if implemented
    }
    return nil  // Skip if not implemented
}
DANGER
Unsafe assertion panics. Always use comma-ok: s, ok := i.(string)
```
Trade-offs
Pros: Flexible, optional behavior
Cons: Runtime overhead, less type safety
Type assertions build on go_interfaces to enable runtime polymorphism.
Quick Reference
// Safe "comma-ok" idiom (recommended)
value, ok := interfaceVar.(ConcreteType)
if ok {
    // use value
}
// Type switch
switch v := i.(type) {
case int:
    fmt.Println("int:", v)
case string:
    fmt.Println("string:", v)
}
// Optional behavior
if validator, ok := v.(Validator); ok {
    validator.Validate()
}
| Pattern | Safety | Use When | 
|---|---|---|
v := i.(T) | Panics | You're certain | 
v, ok := i.(T) | Returns false | Production code | 
switch i.(type) | Safe | Multiple types | 
Examples
EXAMPLE
Type-specific JSON handling:
func ProcessJSON(data interface{}) error {
    switch v := data.(type) {
    case map[string]interface{}:
        return processObject(v)
    case []interface{}:
        return processArray(v)
    case string:
        return processString(v)
    case float64:
        return processNumber(v)
    default:
        return fmt.Errorf("unsupported type: %T", v)
    }
}
Optional Closer pattern:
func ConsumeData(r io.Reader) error {
    data, err := io.ReadAll(r)
    if err != nil {
        return err
    }
    
    // Close only if Reader also implements Closer
    if closer, ok := r.(io.Closer); ok {
        defer closer.Close()
    }
    
    return process(data)
}
// Works with both:
ConsumeData(fileReader)    // Has Close()
ConsumeData(bytes.Buffer)  // No Close() - skipped
Validation middleware:
type Validator interface {
    Validate() error
}
func HandleRequest(w http.ResponseWriter, r *http.Request, payload interface{}) {
    // Decode JSON into payload
    json.NewDecoder(r.Body).Decode(payload)
    
    // Validate only if type implements Validator
    if validator, ok := payload.(Validator); ok {
        if err := validator.Validate(); err != nil {
            http.Error(w, err.Error(), 400)
            return
        }
    }
    
    // Process payload
}
```