From 1f757270d9c6029ae50a03e7f3f852b71751e5c3 Mon Sep 17 00:00:00 2001 From: visualfc Date: Wed, 13 Nov 2024 20:17:41 +0800 Subject: [PATCH] internal/lib/reflect: impl Value.Field --- internal/lib/reflect/value.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/lib/reflect/value.go b/internal/lib/reflect/value.go index 7e632039..0ea69a3e 100644 --- a/internal/lib/reflect/value.go +++ b/internal/lib/reflect/value.go @@ -517,7 +517,6 @@ func ifaceIndir(typ *abi.Type) bool { // Field returns the i'th field of the struct v. // It panics if v's Kind is not Struct or i is out of range. func (v Value) Field(i int) Value { - /* TODO(xsw): if v.kind() != Struct { panic(&ValueError{"reflect.Value.Field", v.kind()}) } @@ -531,7 +530,7 @@ func (v Value) Field(i int) Value { // Inherit permission bits from v, but clear flagEmbedRO. fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind()) // Using an unexported field forces flagRO. - if !field.Name.IsExported() { + if !field.Exported() { if field.Embedded() { fl |= flagEmbedRO } else { @@ -545,8 +544,6 @@ func (v Value) Field(i int) Value { // so v.ptr + field.offset is still the correct address. ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field") return Value{typ, ptr, fl} - */ - panic("todo: reflect.Value.Field") } // FieldByIndex returns the nested field corresponding to index. @@ -2014,6 +2011,14 @@ func (v Value) MethodByName(name string) Value { return v.Method(m.Index) } +// NumField returns the number of fields in the struct v. +// It panics if v's Kind is not Struct. +func (v Value) NumField() int { + v.mustBe(Struct) + tt := (*structType)(unsafe.Pointer(v.typ())) + return len(tt.Fields) +} + // Call calls the function v with the input arguments in. // For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]). // Call panics if v's Kind is not Func.