|
|
@ -28,6 +28,50 @@ func Indirect(v reflect.Value) reflect.Value {
|
|
|
|
return v
|
|
|
|
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
|
|
|
|
// Len get reflect value length
|
|
|
|
func Len(v reflect.Value) int {
|
|
|
|
func Len(v reflect.Value) int {
|
|
|
|
v = reflect.Indirect(v)
|
|
|
|
v = reflect.Indirect(v)
|
|
|
|