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)) {
 | 
					func Walk(x interface{}, fn func(string)) {
 | 
				
			||||||
	val := reflect.ValueOf(x)
 | 
						val := getValue(x)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if val.Kind() == reflect.Pointer {
 | 
					 | 
				
			||||||
		val = val.Elem() // XXX: the object from the pointer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i := 0; i < val.NumField(); i++ {
 | 
						for i := 0; i < val.NumField(); i++ {
 | 
				
			||||||
		field := val.Field(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() {
 | 
							switch field.Kind() {
 | 
				
			||||||
		case reflect.String:
 | 
							case reflect.String:
 | 
				
			||||||
			fn(field.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"
 | 
						"testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Person struct {
 | 
					type Profile struct {
 | 
				
			||||||
	Name    string
 | 
					 | 
				
			||||||
	Profile struct {
 | 
					 | 
				
			||||||
	Age  int
 | 
						Age  int
 | 
				
			||||||
	City string
 | 
						City string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Person struct {
 | 
				
			||||||
 | 
						Name    string
 | 
				
			||||||
 | 
						Profile Profile
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestWalk(t *testing.T) {
 | 
					func TestWalk(t *testing.T) {
 | 
				
			||||||
@ -44,20 +46,22 @@ func TestWalk(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"nested fields",
 | 
								"nested fields",
 | 
				
			||||||
			Person{"Chris", struct {
 | 
								Person{"Chris", Profile{29, "London"}},
 | 
				
			||||||
				Age  int
 | 
					 | 
				
			||||||
				City string
 | 
					 | 
				
			||||||
			}{29, "London"}},
 | 
					 | 
				
			||||||
			[]string{"Chris", "London"},
 | 
								[]string{"Chris", "London"},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"pointer to things",
 | 
								"pointer to things",
 | 
				
			||||||
			&Person{"Chris", struct {
 | 
								&Person{"Chris", Profile{29, "London"}},
 | 
				
			||||||
				Age  int
 | 
					 | 
				
			||||||
				City string
 | 
					 | 
				
			||||||
			}{29, "London"}},
 | 
					 | 
				
			||||||
			[]string{"Chris", "London"},
 | 
								[]string{"Chris", "London"},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"slices",
 | 
				
			||||||
 | 
								[]Profile{
 | 
				
			||||||
 | 
									{29, "London"},
 | 
				
			||||||
 | 
									{33, "Paris"},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								[]string{"London", "Paris"},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, test := range cases {
 | 
						for _, test := range cases {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user