Skip to content

Instantly share code, notes, and snippets.

@zouzias
Created June 13, 2019 09:36
Show Gist options
  • Save zouzias/cd6588a90a0d9868c63d75b60f8351ee to your computer and use it in GitHub Desktop.
Save zouzias/cd6588a90a0d9868c63d75b60f8351ee to your computer and use it in GitHub Desktop.
Golang Reflections Example: https://play.golang.org/p/xXqaBr93HSr
package main
import (
"fmt"
"reflect"
"strings"
)
type Foo struct {
A int
B bool
C string
D float64
E interface{}
N NestedFoo
}
type NestedFoo struct{
Alpha string
Beta string
}
// t := reflect.TypeOf(obj)
// v := reflect.ValueOf(obj)
func nestedGet(t reflect.Type, v reflect.Value, field string) reflect.Value {
nestedFields := strings.Split(field, ".")
firstLevel := nestedFields[0]
rest := strings.Join(nestedFields[1:], ".")
for i := 0; i < v.NumField(); i++ {
if strings.Compare(string(t.Field(i).Name), firstLevel) == 0 {
tp := v.Field(i).Type()
value := v.Field(i)
if len(nestedFields) == 1 {
fmt.Printf("Returning from first level field %s\n", firstLevel)
return value
}
fmt.Printf("Continue recursion on %s\n", rest)
return nestedGet(tp, value, rest)
}
}
fmt.Printf("field name %s was not found. Falling back to original value \n", firstLevel)
return v
}
func main() {
nestedFoo := NestedFoo{"alpha", "beta"}
f := Foo{1, true, "foo", 3.45, nil, nestedFoo}
t := reflect.TypeOf(f)
v := reflect.ValueOf(f)
for i := 0; i < v.NumField(); i++ {
fmt.Printf("OK: %q -> %#v\n", t.Field(i).Name, v.Field(i))
}
// OK: "A" -> 1
// OK: "B" -> true
// OK: "C" -> "foo"
// OK: "D" -> 3.45
// OK: "E" -> interface {}(nil)
t = reflect.TypeOf(f)
v = reflect.ValueOf(f)
value := nestedGet(t, v, "N.Alpha")
fmt.Printf("Value of N.Alpha: %#v\n", value)
value = nestedGet(t, v, "N.Beta")
fmt.Printf("Value of N.Alpha: %#v\n", value)
value = nestedGet(t, v, "N.Notexists")
fmt.Printf("Value of N.Alpha: %#v\n", value)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment