gotdd/reflection.go

58 lines
983 B
Go
Raw Permalink Normal View History

2022-01-20 04:20:12 +00:00
package main
import "reflect"
type Person struct {
Name string
Profile Profile
}
type Profile struct {
Age int
City string
}
func walk(x interface{}, fn func(input string)) {
val := getValue(x)
walkValue := func(value reflect.Value) {
walk(value.Interface(), fn)
}
switch val.Kind() {
case reflect.String:
fn(val.String())
case reflect.Struct:
for i := 0; i < val.NumField(); i++ {
walkValue(val.Field(i))
}
case reflect.Slice, reflect.Array:
for i := 0; i < val.Len(); i++ {
walkValue(val.Index(i))
}
case reflect.Map:
for _, key := range val.MapKeys() {
walkValue(val.MapIndex(key))
}
case reflect.Chan:
for v, ok := val.Recv(); ok; v, ok = val.Recv() {
walkValue(v)
}
case reflect.Func:
valFnResult := val.Call(nil)
for _, res := range valFnResult {
walkValue(res)
}
}
}
func getValue(x interface{}) reflect.Value {
val := reflect.ValueOf(x)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
return val
}