Go's reflection is a powerful feature that allows inspection and manipulation of program types at runtime. It's primarily implemented through the reflect
package.
Why Use Reflection?
- Dynamic Type Checking: Examine variable types and properties at runtime
- Dynamic Invocation: Call functions or methods of unknown types at runtime
- Serialization/Deserialization: Traverse struct fields for JSON parsing
- Frameworks & Libraries: Handle dynamic types in DI and ORM frameworks
Core Concepts
-
Type: Represents Go types using
reflect.Type
-
Value: Represents Go values using
reflect.Value
Basic Operations
1. Getting Reflection Objects
- Use
reflect.TypeOf
for type information - Use
reflect.ValueOf
for value information
2. Type Checking
- Use the
Kind
method to check variable categories
3. Struct Field Operations
- Get and set struct field values, invoke struct methods
Code Examples
Getting Type and Value
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
fmt.Println("value:", reflect.ValueOf(x))
}
Dynamic Value Setting
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
v := reflect.ValueOf(&x)
v = v.Elem()
if v.CanSet() {
v.SetFloat(7.1)
}
fmt.Println(x)
}
Working with Struct Fields
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
p := Person{"Alice", 30}
v := reflect.ValueOf(&p).Elem()
name := v.FieldByName("Name")
age := v.FieldByName("Age")
fmt.Println("Name:", name)
fmt.Println("Age:", age)
if name.CanSet() {
name.SetString("Bob")
}
if age.CanSet() {
age.SetInt(40)
}
fmt.Println("Updated person:", p)
}
Important Considerations
- Performance: Reflection adds overhead; use cautiously in performance-critical code
- Type Safety: Bypasses compile-time type checking, may cause runtime errors
- Exported Fields: Only exported fields (capitalized) can be accessed
Common Use Cases
- Serialization/Deserialization: JSON, XML parsing
- Dependency Injection: Automatic dependency wiring
- ORM Frameworks: Object-relational mapping
Summary
Reflection is a powerful Go feature for runtime type and value manipulation. While it offers great flexibility, consider performance implications and type safety. Use it judiciously based on your specific requirements.
Top comments (0)