Reflection

reflect.Type, reflect.Value, struct tags, and when (not) to use reflection.

Advanced 30 min read 🐹 Go

reflect.TypeOf and reflect.ValueOf

Reflection lets you inspect and manipulate types at runtime. It's used by encoding/json, ORMs, and validation libraries. But it's slow and loses type safety — use sparingly.

import "reflect"

x := 42
t := reflect.TypeOf(x)
v := reflect.ValueOf(x)

fmt.Println("Type:", t)           // int
fmt.Println("Value:", v)          // 42
fmt.Println("Kind:", t.Kind())    // int

Struct Tags

type User struct {
    Name  string `json:"name" validate:"required"`
    Email string `json:"email" validate:"email"`
    Age   int    `json:"age,omitempty"`
}

t := reflect.TypeOf(User{})
for i := 0; i < t.NumField(); i++ {
    field := t.Field(i)
    fmt.Printf("%s: json=%s validate=%s\n",
        field.Name,
        field.Tag.Get("json"),
        field.Tag.Get("validate"))
}
Output
Name: json=name validate=required
Email: json=email validate=email
Age: json=age,omitempty validate=

⚠️ Avoid reflection when possible

Reflection is 10-100x slower than direct code. It bypasses the type system, so errors become runtime panics. Use generics or interfaces first. Only use reflection for truly dynamic scenarios (JSON marshaling, ORM field mapping).

Practice Exercises

Hard Production Scenario

Design a solution using these concepts for a real-world production system.

Hard Performance Analysis

Benchmark two different approaches and explain which is better and why.