golang中 reflect 反射属性和方法
type Person struct {
Name string
Age int
}
func (p *Person) SetAge(newAge int) {
p.Age = newAge
}
func (p Person) GetName() string {
return p.Name
}
func (p Person) SetName(s string) {
p.Name = s
}
func (p Person) NoReturnMethod() {
println("调用了NoReturnMethod巴拉巴拉")
}
1. 操作属性
person := &Person{
Name: "Tom",
Age: 18,
}
// 获取类型
t := reflect.TypeOf(*person)
fmt.Println(t.Name())
// output:
// Person
// 遍历属性字段
v := reflect.ValueOf(person).Elem()
k := v.Type()
for i := 0; i < v.NumField(); i++ {
key := k.Field(i)
val := v.Field(i)
fmt.Printf("%s %T %v
", key.Name, val.Type(), val.Interface())
}
// output:
// Name *reflect.rtype Tom
// Age *reflect.rtype 18
// 设置属性
v.FieldByName("Name").Set(reflect.ValueOf("Jack"))
2. 操作方法
// 遍历方法
for i := 0; i < v.NumMethod(); i++ {
key := k.Method(i)
val := v.Method(i)
fmt.Printf("%s %T %v
", key.Name, val.Type(), val.Interface())
}
// output: // 注意因为变量v是从结构体中取出的所以不包含指针的方法
// GetName *reflect.rtype 0x10ff960
// NoReturnMethod *reflect.rtype 0x10ff960
// SetName *reflect.rtype 0x10ff960
// 调用方法 读取名字
method_GetName := v.MethodByName("GetName")
name := method_GetName.Call([]reflect.Value{})
fmt.Println(name)
// output:
// [Jack]
// 注意:要使用指针的方法需要取出指针类型的Elem()
v2 := reflect.ValueOf(&person).Elem()
// 遍历方法
for i, k2 := 0, v2.Type(); i < v2.NumMethod(); i++ {
key := k2.Method(i)
val := v2.Method(i)
fmt.Printf("%s %T %v
", key.Name, val.Type(), val.Interface())
}
// output:
// GetName *reflect.rtype 0x10ff960
// NoReturnMethod *reflect.rtype 0x10ff960
// SetAge *reflect.rtype 0x10ff960
// SetName *reflect.rtype 0x10ff960
// 调用指针方法,修改年龄,改成28
method_SetAge := (v2).MethodByName("SetAge")
// 判断是否成功获取到方法
if method_SetAge.IsValid() == true {
method_SetAge.Call([]reflect.Value{reflect.ValueOf(28)})
}
fmt.Println("新年龄:", person.Age)
// output:
// 新年龄:28
// 调用无返回值的函数,不接收就行了
v.MethodByName("NoReturnMethod").Call([]reflect.Value{})
// output:
// 调用了NoReturnMethod巴拉巴拉