Пакет reflect позволяет исследовать и изменять типы и значения в runtime. Два ключевых типа: reflect.Type и reflect.Value.
x := 42
t := reflect.TypeOf(x) // int
v := reflect.ValueOf(x) // reflect.Value содержащий 42
fmt.Println(t.Kind()) // int
fmt.Println(v.Int()) // 42
Изменение значения через reflection (нужен указатель):
x := 42
v := reflect.ValueOf(&x).Elem()
v.SetInt(100) // x теперь 100
Итерация по полям структуры:
type User struct {
Name string json:"name"
Age int json:"age"
}
t := reflect.TypeOf(User{})
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fmt.Println(f.Name, f.Tag.Get("json"))
}
Reflect медленный и небезопасный. Используй только когда без него никак (ORM, сериализация, DI). С появлением generics потребность снизилась.