From a66fe300cdc2269aebdfb08745d0f1205254f07c Mon Sep 17 00:00:00 2001 From: NoahLan <6995syu@163.com> Date: Wed, 23 Aug 2023 10:45:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=8E=B7=E5=8F=96ref?= =?UTF-8?q?lect.Value=E5=AE=9E=E9=99=85=E6=8C=87=E5=90=91=E7=9A=84?= =?UTF-8?q?=E5=8F=8D=E5=B0=84=E5=AF=B9=E8=B1=A1=E7=9A=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E8=87=AA=E5=8A=A8=E6=96=B0=E5=BB=BA=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nreflect/util.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/nreflect/util.go b/nreflect/util.go index f26dd0d..ab9cfdb 100644 --- a/nreflect/util.go +++ b/nreflect/util.go @@ -28,6 +28,50 @@ func Indirect(v reflect.Value) reflect.Value { return v } +// IndirectAddr walks down v allocating pointers as needed, +// until it gets to a non-pointer. +func IndirectAddr(v reflect.Value) reflect.Value { + v0 := v + haveAddr := false + + // 如果v是命名类型并且可寻址(非指针) + if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + haveAddr = true + v = v.Addr() + } + for { + // 从接口加载值,但前提是结果可有效寻址。 + if v.Kind() == reflect.Interface && !v.IsNil() { + e := v.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() && e.Elem().Kind() == reflect.Ptr { + haveAddr = false + v = e + continue + } + } + if v.Kind() != reflect.Ptr { + break + } + // 防止无限循环,v有可能是是指向其自身地址的接口: + // var v any + // v = &v + if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v { + v = v.Elem() + break + } + if v.IsNil() && v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } + if haveAddr { + v = v0 // 返回原始值,如果可寻址 + haveAddr = false + } else { + v = v.Elem() + } + } + return v +} + // Len get reflect value length func Len(v reflect.Value) int { v = reflect.Indirect(v)