(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)
// 創(chuàng)建新對象
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