diff options
Diffstat (limited to 'src/pkg/reflect')
-rw-r--r-- | src/pkg/reflect/type.go | 16 | ||||
-rw-r--r-- | src/pkg/reflect/value.go | 10 |
2 files changed, 21 insertions, 5 deletions
diff --git a/src/pkg/reflect/type.go b/src/pkg/reflect/type.go index a8df033af..eb1ba52a9 100644 --- a/src/pkg/reflect/type.go +++ b/src/pkg/reflect/type.go @@ -507,7 +507,7 @@ func (t *StructType) FieldByIndex(index []int) (f StructField) { const inf = 1 << 30 // infinity - no struct has that many nesting levels -func (t *StructType) fieldByName(name string, mark map[*StructType]bool, depth int) (ff StructField, fd int) { +func (t *StructType) fieldByNameFunc(match func(string) bool, mark map[*StructType]bool, depth int) (ff StructField, fd int) { fd = inf // field depth if mark[t] { @@ -522,7 +522,7 @@ L: for i, _ := range t.fields { f := t.Field(i) d := inf switch { - case f.Name == name: + case match(f.Name): // Matching top-level field. d = depth case f.Anonymous: @@ -531,13 +531,13 @@ L: for i, _ := range t.fields { ft = pt.Elem() } switch { - case ft.Name() == name: + case match(ft.Name()): // Matching anonymous top-level field. d = depth case fd > depth: // No top-level field yet; look inside nested structs. if st, ok := ft.(*StructType); ok { - f, d = st.fieldByName(name, mark, depth+1) + f, d = st.fieldByNameFunc(match, mark, depth+1) } } } @@ -576,7 +576,13 @@ L: for i, _ := range t.fields { // FieldByName returns the struct field with the given name // and a boolean to indicate if the field was found. func (t *StructType) FieldByName(name string) (f StructField, present bool) { - if ff, fd := t.fieldByName(name, make(map[*StructType]bool), 0); fd < inf { + return t.FieldByNameFunc(func(s string) bool { return s == name }) +} + +// FieldByNameFunc returns the struct field with a name that satisfies the +// match function and a boolean to indicate if the field was found. +func (t *StructType) FieldByNameFunc(match func(string) bool) (f StructField, present bool) { + if ff, fd := t.fieldByNameFunc(match, make(map[*StructType]bool), 0); fd < inf { ff.Index = ff.Index[0 : fd+1] f, present = ff, true } diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go index f21c564d5..d8ddb289a 100644 --- a/src/pkg/reflect/value.go +++ b/src/pkg/reflect/value.go @@ -1251,6 +1251,16 @@ func (t *StructValue) FieldByName(name string) Value { return nil } +// FieldByNameFunc returns the struct field with a name that satisfies the +// match function. +// The result is nil if no field was found. +func (t *StructValue) FieldByNameFunc(match func(string) bool) Value { + if f, ok := t.Type().(*StructType).FieldByNameFunc(match); ok { + return t.FieldByIndex(f.Index) + } + return nil +} + // NumField returns the number of fields in the struct. func (v *StructValue) NumField() int { return v.typ.(*StructType).NumField() } |