CodeNebula
Go🚀Advancedadvanced

Reflection

Go · Advanced · Run with go run

Explanation

The `reflect` package allows inspecting and manipulating values at runtime without compile-time type knowledge. `reflect.TypeOf(v)` returns the type; `reflect.ValueOf(v)` returns the value. Reflection is used in serialization libraries (encoding/json), ORMs, dependency injection frameworks, and test utilities. It is slower than direct code — use it when compile-time polymorphism (interfaces or generics) is not sufficient.

Real-World Scenario

A struct validator iterates over fields using reflection, checking `validate:` struct tags: `required`, `min`, `max`. This lets one validation function work for any struct type without code generation.

Quick Snippet

snippet.go
import "reflect"

func printFields(v any) {
    rv := reflect.ValueOf(v)
    rt := reflect.TypeOf(v)

    if rv.Kind() == reflect.Ptr {
        rv = rv.Elem()
        rt = rt.Elem()
    }

    for i := 0; i < rv.NumField(); i++ {
        field := rt.Field(i)
        value := rv.Field(i)
        tag := field.Tag.Get("json")
        fmt.Printf("Field: %s, Tag: %s, Value: %v\n",
            field.Name, tag, value)
    }
}

type Config struct {
    Host string `json:"host"`
    Port int    `json:"port"`
}
printFields(Config{"localhost", 8080})

Full Example

reflection.go
// Compile: go run reflection.go
// Output:
//   Field: Host  Tag: host  Value: localhost
//   Field: Port  Tag: port  Value: 8080
package main

import (
	"fmt"
	"reflect"
)

type Config struct {
	Host string `json:"host"`
	Port int    `json:"port"`
}

func printFields(v any) {
	rv := reflect.ValueOf(v)
	rt := reflect.TypeOf(v)

	if rv.Kind() == reflect.Ptr {
		rv = rv.Elem()
		rt = rt.Elem()
	}

	for i := 0; i < rv.NumField(); i++ {
		field := rt.Field(i)
		value := rv.Field(i)
		tag := field.Tag.Get("json")
		fmt.Printf("Field: %s  Tag: %s  Value: %v\n", field.Name, tag, value)
	}
}

func main() {
	printFields(Config{Host: "localhost", Port: 8080})
}
Run command
go run reflection.go