Mastering Go Reflection: A Comprehensive Guide from Basics to Advanced πŸš€

ym qu - Oct 26 - - Dev Community

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?

  1. Dynamic Type Checking: Examine variable types and properties at runtime
  2. Dynamic Invocation: Call functions or methods of unknown types at runtime
  3. Serialization/Deserialization: Traverse struct fields for JSON parsing
  4. Frameworks & Libraries: Handle dynamic types in DI and ORM frameworks

Core Concepts

  1. Type: Represents Go types using reflect.Type
  2. 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))
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

Important Considerations

  1. Performance: Reflection adds overhead; use cautiously in performance-critical code
  2. Type Safety: Bypasses compile-time type checking, may cause runtime errors
  3. Exported Fields: Only exported fields (capitalized) can be accessed

Common Use Cases

  1. Serialization/Deserialization: JSON, XML parsing
  2. Dependency Injection: Automatic dependency wiring
  3. 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.

. . . . . . .