(value) Elem()
如果value是空接口类型,返回其具体的值
如果是指针,返回指向的内容
(type) Elem()
如果type是array、chanel、slice,返回其元素type
如果是map,返回 v 的type
如果是指针,返回指向内容的type
Indirect()
如果是指针,返回其指向的值
如果不是指针的话,返回Elem()
func Indirect(v Value) Value {
if v.Kind() != Ptr {
return v
}
return v.Elem()
}
用反射修改一个对象的值
这里遇到了一个小坑,那就是当对象没有暴露出来的时候(首字母没有大写),会失败,出现这个错误 panic: reflect: reflect.Value.SetInt using value obtained using unexported field
type Geek struct {
A int `tag1:"First Tag" tag2:"Second Tag"`
B string
}
f := Geek{A: 10, B: "Number"}
fmt.Println(f)
// {10 Number}
// 必须传址,传值无法修改
fval := reflect.ValueOf(&f)
// 如果没有Elem()的话,会panic: reflect: call of reflect.Value.Field on ptr Value
fval.Elem().Field(0).SetInt(14)
fval.Elem().Field(1).SetString("fads")
fmt.Println(f)
// {14 fads}
New()
有点等同于reflect.ValueOf(&value)
但是用法不一样。
要传入一个reflect.Type,构建出一个新的对象,可以set值进去。
example
type Geek struct {
A int `tag1:"First Tag" tag2:"Second Tag"`
B string
}
f := Geek{A: 10, B: "Number"}
// 拿到 Type
fType := reflect.TypeOf(f)
// 创建新对象
fVal := reflect.New(fType)
// 可以设置值
fVal.Elem().Field(0).SetInt(20)
fVal.Elem().Field(1).SetString("Number")
Addr()
拿到被反射对象的地址,一般是用 .Addr().Interface() 这样用的
f := Geek{A: 10, B: "Number"}
fmt.Println(uintptr(unsafe.Pointer(&f)))
// 824634400800
fval := reflect.ValueOf(&f).Elem()
s := fval.Addr().Pointer()
// 824634400800
k := fval.Addr().Interface()
fmt.Println(s == &f)
// true
网友评论