package walk import ( "reflect" ) func Walk(x interface{}, fn func(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++ { // XXX: Interface() to get interface 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)) } } } func getValue(x interface{}) reflect.Value { val := reflect.ValueOf(x) if val.Kind() == reflect.Pointer { return val.Elem() } return val }