Golang基础--10--反射reflection

匿名 (未验证) 提交于 2019-12-03 00:27:02

Ŀ¼

  • 反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地
  • 反射使用TypeOf和ValueOf函数从 接口 中获取目标对象信息
type User struct{     Id int     Name string     Age int } func (u User) Hello() {     fmt.Println("Hello World.") } func main(){     u := User{1,"kk",12}     Info(u) } func Info(o interface{}){     //获取类型信息     t := reflect.TypeOf(o)     fmt.Println("Type:",t.Name())      //用以判断传入的类型是否是struct类型,而不是指针什么的     if k:=t.Kind();k!=reflect.Struct {         fmt.Println("XXXXXXXXXX")         return     }      //获取字段信息     v := reflect.ValueOf(o)     fmt.Println("Field:")      for i:=0;i<t.NumField();i++ {         f := t.Field(i)         val :=  v.Field(i).Interface()         fmt.Printf("%6s: %v = %v\n",f.Name,f.Type,val)      //获取方法信息     for i:= 0;i<t.NumMethod();i++ {         m := t.Method(i)         fmt.Printf("%6s: %v\n",m.Name,m.Type)     } } /* > Output: command-line-arguments Type: User Field:     Id: int = 1   Name: string = kk    Age: int = 12  Hello: func(main.User) */
  • 反射会将匿名字段作为独立字段(匿名字段本质)
type User struct {     Id int     Name string     Age int } //匿名字段 type Manager struct {     User     title string } func main(){     m := Manager{User: User{1,"hel",12}, title:"123"}     t := reflect.TypeOf(m)     //通过slice获取值     fmt.Printf("%#v\n",t.FieldByIndex([]int{0,0})) } /* > Output: command-line-arguments reflect.StructField{Name:"Id", PkgPath:"", Type:(*reflect.rtype)(0x49ce80), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false} */
  • 想要利用反射修改对象状态,前提是interface.data是settable,即pointer-interface
type User struct {     Id int     Name string     Age int } type Manager struct {     User     title string } func main(){     u := User{1,"ok",12}     Set(&u)     fmt.Println(u) } //通过ptr(point interface)修改字段的值 func Set(o interface{}) {     v := reflect.ValueOf(o)     if v.Kind()!=reflect.Ptr&&!v.Elem().CanSet(){         fmt.Println("XXX")         return     }else{         v = v.Elem()     }     f:=v.FieldByName("Name")     if !f.IsValid(){         fmt.Println("BAD")         return     }     if f.Kind()==reflect.String {         f.SetString("BYBYBY")     } } /* > Output: command-line-arguments {1 BYBYBY 12} */
  • 通过反射可以“动态”调用方法
type User struct {     Id int     Name string     Age int } func (u User)Hello(name string) {     fmt.Println("Hello",name,", my name is",u.Name) } func main() {     u := User{1,"OK",12}     v := reflect.ValueOf(u)     mv := v.MethodByName("Hello")     //args是个slice,     //利用反射动态调用     args := []reflect.Value{reflect.ValueOf("joe")}     mv.Call(args) } /* > Output: command-line-arguments Hello joe , my name is OK */
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!