Reflection reflex
- Reflection can greatly increase the flexibility of the program, so that interface{} has a greater scope of play
- Reflection uses the TypeOf and valueof functions to get target object information from the interface
- Reflection will use anonymous fields as separate fields (anonymous field nature)
- You want to use reflection to modify the state of an object, if Interface.data is settable, which is pointer-interface
- The method can be called "dynamic" by reflection
Example 1, using reflection to obtain attribute information, method information
Reflection exercises//Get field type information, method information, property information package Mainimport ("FMT" "reflect") type User struct {Id int Name string Ag e int}func (user user) Hello () {fmt. Println ("Hello World")}func main () {User: = User{id:2, Name: "Xiaoqiang", age:30} info (user)}//define a method//This method receives an empty interface// In this case, actually any type can receive the Func info (o interface{}) {//Get O of type T: = reflect. TypeOf (o) fmt. Println ("Type:\t", T.name ())//remove type, you need to verify the type,//See if it is the specified type if K: =t.kind (); K! = reflect. struct {//if it is not a specified struct type, it is necessary to do//exception handling FMT. Println ("The type of the input parameter does not match!") return}//Get the property of O V: = reflect. ValueOf (o) fmt. Println ("fields:\n")//Start traversal, output field for I: = 0; I < T.numfield (); i++ {//Gets the property subscript f: = T.field (i) Val: = V.field (i). Interface ()//The name of the output attribute, type, corresponding to the value FMT. Printf ("%6s:%v =%v\n", F.name, F.type, Val)}//start getting basic information for the method for i:=0; I<t.nummethod (); i++ {m: = T.method (i) fmt. Printf ("%6s:%v\n", M.name, M.type)}}
2. How does reflection get anonymous fields?
//反射 是如何处理 匿名字段的?package mainimport ( "reflect" "fmt")type Stu struct { Id int Name string Age int}type Man struct { //这里你要注意一下,你创建的属性,是有顺序的,是有下标的 //如Stu 下标 就是0, title下标就是1 // Stu 就是匿名属性 Stu title string}func main() { //注意,对匿名字段进行初始化时的方式,其实本质上跟其他属性是一样的 m := Man{Stu:Stu{Id:2,Name:"Jack",Age:19}, title:"Manager"} t := reflect.TypeOf(m) //取匿名字段的方式 //FieldByIndex 方法,传入的是一个切片slice类型 //第1个0,表示,匿名字段在Man中的下标位置 //第2个0,表示,你要取匿名字段中哪个属性的下标 fmt.Printf("%#v\n", t.FieldByIndex([]int{0,0})) //取的是id fmt.Printf("%#v\n", t.FieldByIndex([]int{0,1})) //取的是Name fmt.Printf("%#v\n", t.FieldByIndex([]int{0,2})) //取的是Age}
3. Modify the basic type by reflection
//如果通过反射,对基本类型进行修改package mainimport ( "reflect" "fmt")func main() { //下面测试,对基本类型的修改 操作 x := 456 //传递的参数是 地址 v := reflect.ValueOf(&x) //Elem方法,是取出元素值来,然后通过setint方法,进行重新设置 v.Elem().SetInt(789) fmt.Println(x)}
4. Modification of complex types by reflection
//如果通过反射,对复杂类型进行修改package mainimport ( "reflect" "fmt")type Teac struct { Id int Name string Age int}func main() { teac := Teac{Id:5,Name:"Ant-man",Age:23} fmt.Println("teac:\t", teac) //传递的是 地址哦 Set(&teac) fmt.Println("teac:\t", teac)}func Set(o interface{}) { v := reflect.ValueOf(o) if v.Kind() == reflect.Ptr && !v.Elem().CanSet() { fmt.Printf("xxx") return }else{ v = v.Elem() } // 通过FieldByName 这个方法,直接输入 名称,来获取 f := v.FieldByName("Name") //校验,是否取到Name属性的值 if !f.IsValid() { fmt.Printf("BAD") return } //然后,再校验,类型是否匹配 if f.Kind() == reflect.String { f.SetString("Iron Man") }}
5. Dynamic invocation of the method through reflection
//通过反射,进行方法的调用,相当于动态调用了package mainimport ( "fmt" "reflect")type Teacher struct { Id int Name string Age int}//通过receiver将Show方法,跟Teacher类型,进行绑定func (teacher Teacher)Show(name string) { fmt.Println("hello, ", name, ", my name is ", teacher.Name)}//注意======目前没有发现====如何通过====反射===来获取=====私有方法func (teacher Teacher)info(){ fmt.Println("=====")}func main() { teacher := Teacher{Id:34, Name:"Thor",Age:34} teacher.Show("Hawkeye") //下面通过反射,调用show方法 v := reflect.ValueOf(teacher) //获取show方法 m := v.MethodByName("Show") //校验一下,是否获取到show方法呢 if !m.IsValid() { fmt.Printf("=======没有获取到制定的方法====") return } //参数必须是切片类型 //reflect.Value{} 这里面,可以设定多个参数类型 //目前,我们这里只有一个string类型的参数 // args := []reflect.Value{reflect.ValueOf("Hulk")} m.Call(args)}
The reflection of Go language