Using FieldByName
As with all things in Go reflection, there are a few ways to go about doing things which will be more or less useful depending on your application. See: https://pkg.go.dev/reflect#Value.FieldByName. You could use a similar approach with Field.
package main
import (
"log"
"reflect"
)
type Root struct {
One Nested
Two Nested
}
type Nested struct {
i int
s string
}
func main() {
r := Root{
One: Nested{i: 1, s: "one"},
Two: Nested{i: 2, s: "two"},
}
rv := reflect.Indirect(reflect.ValueOf(&r))
rt := rv.Type()
for i, limit := 0, rt.NumField(); i < limit; i++ {
fld := rt.Field(i)
v := rv.FieldByName(fld.Name).Addr().Interface()
nv, ok := v.(*Nested)
if !ok {
log.Fatalf("field is type %T not Nested", v)
}
log.Printf("field name: %s, type: %T, i: %v, s: %v", fld.Name, v, nv.i, nv.s)
}
}
2022/09/05 16:25:56 field name: One, type: *main.Nested, i: 1, s: one
2022/09/05 16:25:56 field name: Two, type: *main.Nested, i: 2, s: two
Using a map
I would think hard about your architectural choices. In my experience, there are relatively few problems that reflection can solve that can't also be solved by better design/data structure choices. For example:
package main
import (
"log"
)
type Nested struct {
i int
s string
}
func main() {
r := map[string]*Nested{
"One": {i: 1, s: "one"},
"Two": {i: 2, s: "two"},
}
for k, v := range r {
log.Printf("key name: %s, type: %T, i: %v, s: %v", k, v, v.i, v.s)
}
}
2022/09/05 16:31:46 key name: One, type: *main.Nested, i: 1, s: one
2022/09/05 16:31:46 key name: Two, type: *main.Nested, i: 2, s: two
Using a method
If you can live without the field name and won't be expanding the Root structure, you can define a simple helper method to let you iterate through the fields:
package main
import (
"log"
)
type Root struct {
One Nested
Two Nested
}
func (r *Root) Array() []*Nested {
return []*Nested{&r.One, &r.Two}
}
type Nested struct {
i int
s string
}
func main() {
r := Root{
One: Nested{i: 1, s: "one"},
Two: Nested{i: 2, s: "two"},
}
for _, v := range r.Array() {
log.Printf("type: %T, i: %v, s: %v", v, v.i, v.s)
}
}
2022/09/05 16:38:01 type: *main.Nested, i: 1, s: one
2022/09/05 16:38:01 type: *main.Nested, i: 2, s: two