Skip to content

Instantly share code, notes, and snippets.

@KuthumiPepple
Created April 2, 2022 20:18
Show Gist options
  • Save KuthumiPepple/ac385c7da4343123a131f580b34f198e to your computer and use it in GitHub Desktop.
Save KuthumiPepple/ac385c7da4343123a131f580b34f198e to your computer and use it in GitHub Desktop.
Walk function takes a struct and a function as arguments and calls the function for all string fields found inside the struct. The use of reflection is demonstrated here.
package reflection
import "reflect"
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() {
Walk(v.Interface(), fn)
}
case reflect.Func:
valFnResult := val.Call(nil)
for _, res := range valFnResult {
Walk(res.Interface(), fn)
}
}
}
func getValue(x interface{}) reflect.Value {
val := reflect.ValueOf(x)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
return val
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment