🪞 Go – Reflection Explained with reflect
Package, Examples & Use Cases (2025 Guide)
🧲 Introduction – What Is Reflection in Go?
Reflection in Go is the ability to inspect and manipulate types, values, and structure at runtime. Go achieves this through the reflect
package, which enables developers to build dynamic tools, serialization utilities, generic functions, and even framework-like behavior without knowing the exact types at compile time.
🎯 In this section, you’ll learn:
- How reflection works using
reflect.Type
andreflect.Value
- Inspect types and values dynamically
- Modify struct fields and methods at runtime
- Real-world use cases and performance cautions
✅ Import the reflect
Package
import (
"fmt"
"reflect"
)
✅ The core of Go reflection is in the standard reflect
package.
🔍 Inspecting Type and Value
var x = 42
fmt.Println(reflect.TypeOf(x)) // Output: int
fmt.Println(reflect.ValueOf(x)) // Output: 42
✅ reflect.TypeOf()
returns the type, and reflect.ValueOf()
returns the value as a reflect.Value
object.
🧪 Getting Kind of a Type
x := "hello"
v := reflect.ValueOf(x)
fmt.Println(v.Kind()) // Output: string
✅ Kind
tells you the general category like int
, slice
, struct
, ptr
.
📦 Access Struct Fields Using Reflection
type User struct {
Name string
Age int
}
u := User{"Alice", 25}
val := reflect.ValueOf(u)
for i := 0; i < val.NumField(); i++ {
fmt.Println("Field", i, ":", val.Field(i))
}
📤 Output:
Field 0 : Alice
Field 1 : 25
✅ Useful for struct introspection, such as building serializers or loggers.
🛠️ Modifying Fields with Pointers
type Config struct {
Debug bool
}
cfg := Config{Debug: false}
v := reflect.ValueOf(&cfg).Elem()
if v.Kind() == reflect.Struct {
f := v.FieldByName("Debug")
if f.IsValid() && f.CanSet() {
f.SetBool(true)
}
}
fmt.Println(cfg.Debug) // Output: true
✅ You need a pointer and check CanSet()
to modify struct fields using reflection.
🔁 Iterate and Inspect Types Dynamically
func PrintTypes(values ...interface{}) {
for _, val := range values {
fmt.Println("Type:", reflect.TypeOf(val), "Value:", val)
}
}
PrintTypes(1, "test", 3.14)
📤 Output:
Type: int Value: 1
Type: string Value: test
Type: float64 Value: 3.14
✅ Perfect for writing generic logging and inspection tools.
⚙️ Reflect and Interfaces
var data interface{} = 100
v := reflect.ValueOf(data)
fmt.Println(v.Int()) // Output: 100
✅ Reflection is commonly used with interface{}
, where static types aren’t known.
⚠️ Performance Warning
Reflection in Go:
- ❌ Is slower than regular type-safe code
- ❌ Breaks compile-time safety
- ✅ Should be used only when necessary
🧠 Best Practices
Practice | Reason |
---|---|
✅ Use reflection sparingly | Prefer compile-time safety |
✅ Always check Kind and CanSet | Avoid panics during unsafe operations |
❌ Don’t overuse for simple logic | Leads to complex, hard-to-maintain code |
✅ Combine with tags for flexibility | Great for parsers, serializers, validators |
📌 Summary – Recap & Next Steps
Reflection provides a way to write dynamic, type-agnostic programs in Go. While powerful, it must be used cautiously to avoid performance loss and maintain readability.
🔍 Key Takeaways:
- Use
reflect.TypeOf()
andreflect.ValueOf()
to inspect runtime types and values - Use reflection for struct field inspection, dynamic method calls, and generic utilities
- Always check
Kind()
,IsValid()
, andCanSet()
before operations - Use pointers to modify values via reflection
⚙️ Next: Explore Struct Tags with Reflection, or dive into Go Generics vs Reflection.
❓ FAQs – Go Reflection
❓ What is reflection used for in Go?
✅ It’s used to inspect or modify values/types at runtime, useful in ORMs, JSON parsing, and dynamic function handling.
❓ Can I modify struct fields using reflection?
✅ Yes, but you must pass a pointer, and the field must be exported and CanSet()
.
❓ Is reflection type-safe in Go?
❌ No. Improper use can cause panics. Always validate kinds and types before accessing.
❓ How do I check the type of a variable at runtime?
✅ Use reflect.TypeOf(variable)
. Use Kind()
to get generalized type info like int
, slice
, etc.
❓ When should I avoid reflection in Go?
✅ When static types can solve the problem—reflection should be a last resort.
Share Now :