Go语言的反射
Home
- 反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地
- 反射使用TypeOf和ValueOf函数从接口中获取目标对象信息
- 反射会将匿名字段作为独立字段(匿名字段的本质)
- 想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface
- 通过反射可以动态调用方法
代码例子
反射使用TypeOf和ValueOf函数从接口中获取目标对象信息
package main
import(
"fmt"
"reflect"
)
type User struct{
name string
age string
}
func (u User)Hello(){
fmt.Println("Hello Reflection")
}
func main(){
u := User{"zuo",22}
info(u)
}
func Info(o interface{}){
t := reflect.TypeOf(o)
fmt.Println("Type":t.Name())
if k := t.Kind();k!=reflect.Struct{
fmt.Println("传进来的接口为指针,不能继续")
return
}
v := reflect.ValueOf(o)
for i := 0;i<t.NumField();i++{
f = t.Field(i)
val := v.Field(i).Interface()
fmt.Printf("%6s:%v = %v\n",f.Name,t.Type,val)
}
for i := 0;i<t.NumMethod();i++{
m := t.Method(i)
fmt.Printf("%6s:%v\n",m.Name,m.Type)
}
}
反射会将匿名字段作为独立字段
import(
"fmt"
"reflect"
)
type User struct{
name string
age int
}
type Manager struct {
User // 匿名字段
title string
}
func main(){
m := Manager{User:User{"zuo",22},title:"主题"}
t :=reflect.TypeOf(m)
fmt.Printf("%#v\n",t.Field(0))
//输出:reflect.StructField{Name:"User", PkgPath:"", Type:(*reflect.rtype)(0x10aeda0), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
fmt.Printf("%#v\n",t.Field(1))
//输出:reflect.StructField{Name:"title", PkgPath:"main", Type:(*reflect.rtype)(0x10a2ea0), Tag:"", Offset:0x18, Index:[]int{1}, Anonymous:false}
fmt.Printf("%#v\n",t.FieldByIndex([]int{0,0}
))
//根据索引取值
//输出:reflect.StructField{Name:"name", PkgPath:"main", Type:(*reflect.rtype)(0x10a2f80), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}
}
想要利用反射修改对象状态
待补充