Ŀ¼
- 反射可大大提高程序的灵活性,使得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() fmt.Println("XXXXXXXXXX") return } //获取字段信息 v := reflect.ValueOf(o) fmt.Println("Field:") for i:=0 f := t.Field(i) val := v.Field(i).Interface() fmt.Printf("%6s: %v = %v\n",f.Name,f.Type,val) //获取方法信息 for i:= 0 m := t.Method(i) fmt.Printf("%6s: %v\n",m.Name,m.Type) } }
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) } 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") } }
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 := []reflect.Value{reflect.ValueOf("joe")} mv.Call(args) }