walk: deal with slices
This commit is contained in:
		
							
								
								
									
										20
									
								
								walk/walk.go
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								walk/walk.go
									
									
									
									
									
								
							@ -5,15 +5,17 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Walk(x interface{}, fn func(string)) {
 | 
			
		||||
	val := reflect.ValueOf(x)
 | 
			
		||||
 | 
			
		||||
	if val.Kind() == reflect.Pointer {
 | 
			
		||||
		val = val.Elem() // XXX: the object from the pointer
 | 
			
		||||
	}
 | 
			
		||||
	val := getValue(x)
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < val.NumField(); i++ {
 | 
			
		||||
		field := val.Field(i)
 | 
			
		||||
 | 
			
		||||
		if val.Kind() == reflect.Slice {
 | 
			
		||||
			for i := 0; i < val.Len(); i++ {
 | 
			
		||||
				Walk(val.Index(i).Interface(), fn)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch field.Kind() {
 | 
			
		||||
		case reflect.String:
 | 
			
		||||
			fn(field.String())
 | 
			
		||||
@ -23,3 +25,11 @@ func Walk(x interface{}, fn func(string)) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getValue(x interface{}) reflect.Value {
 | 
			
		||||
	val := reflect.ValueOf(x)
 | 
			
		||||
	if val.Kind() == reflect.Pointer {
 | 
			
		||||
		return val.Elem()
 | 
			
		||||
	}
 | 
			
		||||
	return val
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,12 +5,14 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Person struct {
 | 
			
		||||
	Name    string
 | 
			
		||||
	Profile struct {
 | 
			
		||||
type Profile struct {
 | 
			
		||||
	Age  int
 | 
			
		||||
	City string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Person struct {
 | 
			
		||||
	Name    string
 | 
			
		||||
	Profile Profile
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestWalk(t *testing.T) {
 | 
			
		||||
@ -44,20 +46,22 @@ func TestWalk(t *testing.T) {
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"nested fields",
 | 
			
		||||
			Person{"Chris", struct {
 | 
			
		||||
				Age  int
 | 
			
		||||
				City string
 | 
			
		||||
			}{29, "London"}},
 | 
			
		||||
			Person{"Chris", Profile{29, "London"}},
 | 
			
		||||
			[]string{"Chris", "London"},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"pointer to things",
 | 
			
		||||
			&Person{"Chris", struct {
 | 
			
		||||
				Age  int
 | 
			
		||||
				City string
 | 
			
		||||
			}{29, "London"}},
 | 
			
		||||
			&Person{"Chris", Profile{29, "London"}},
 | 
			
		||||
			[]string{"Chris", "London"},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"slices",
 | 
			
		||||
			[]Profile{
 | 
			
		||||
				{29, "London"},
 | 
			
		||||
				{33, "Paris"},
 | 
			
		||||
			},
 | 
			
		||||
			[]string{"London", "Paris"},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, test := range cases {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user