DEV Community

Yash-007
Yash-007

Posted on

Reflection in Go — When You Need to Work with the Unknown

Go is a statically typed language, which means you usually know the type of every variable at compile time. but sometimes you don’t especially when working with interface{} and that’s when reflection becomes useful.

The reflect package in Go allows your program to inspect and even modify types and values at runtime.

reflect.TypeOf and reflect.ValueOf

These two are the entry points for using reflection in Go:

TypeOf() gives the static type.
ValueOf() gives the runtime value.

x := 3.14

t := reflect.TypeOf(x)   // float64
v := reflect.ValueOf(x)  // 3.14

fmt.Println("Type:", t)
fmt.Println("Kind:", t.Kind()) // float64

Enter fullscreen mode Exit fullscreen mode

Reading Struct Fields at Runtime

Reflection lets you loop through struct fields dynamically:

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

u := User{"Yash", 30}
v := reflect.ValueOf(u)
t := reflect.TypeOf(u)

for i := 0; i < v.NumField(); i++ {
    field := t.Field(i)
    fmt.Println("Field:", field.Name)
    fmt.Println("Value:", v.Field(i))
    fmt.Println("Tag:", field.Tag.Get("json"))
}

Enter fullscreen mode Exit fullscreen mode

This is exactly what libraries like encoding/json or gorm do under the hood read struct fields and tags at runtime to decide how to handle data.

Modifying a Value Using Reflection

If you want to update a variable through reflection, you need to pass a pointer:

x := 3.4
v := reflect.ValueOf(&x) // pass pointer
v.Elem().SetFloat(7.1)

fmt.Println(x) // 7.1

Enter fullscreen mode Exit fullscreen mode

Trying to modify a non-pointer value will result in a panic.

Dynamically Calling Methods

You can even call methods by their name:

type MyType struct{}

func (m MyType) SayHello(name string) {
    fmt.Println("Hello", name)
}

v := reflect.ValueOf(MyType{})
method := v.MethodByName("SayHello")
method.Call([]reflect.Value{reflect.ValueOf("Yash")}) // Output: Hello Yash

Enter fullscreen mode Exit fullscreen mode

Reflection is heavily used in the Go ecosystem. some common examples:

  • encoding/json for marshaling and unmarshaling structs
  • GORM (ORM library) to map Go structs to database tables
  • Validation libraries (like go playground/validator)
  • Logging tools, serialization frameworks, CLI parsers, etc.

End:

Reflection is powerful, but:

It’s slower than regular code
You lose compile time type safety
It can make code harder to understand
So use it only when you really need dynamic behavior.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.