package main; import ( "fmt" "reflect" ) //反射refection //反射使用TypeOf和ValueOf函数从接口中获取目标对象信息 //反射会将匿名字段作为独立字段 type A struct { id int; name string; age int; } type B struct { A height int; } type C struct { Id int; Name string; Age int; } func (a A) Hello() { fmt.Println("A"); } func (c C) Hello(msg string) { fmt.Println(msg); } func info(inf interface{}) { t := reflect.TypeOf(inf); fmt.Println(t.Name()); v := reflect.ValueOf(inf); //遍历出结构中的字段名,字段类型和值 for i := 0; i < t.NumField(); i++ { f := t.Field(i); val := v.Field(i); fmt.Println(f.Name, f.Type, val); } //遍历出方法,注意这里只遍历出公开方法 for i := 0; i < t.NumMethod(); i++ { m := t.Method(i); fmt.Println(m.Name, m.Type); } } func main() { a := A{1, "test", 25}; a.Hello(); info(a); b := B{A: A{id: 2, name: "test2", age: 28}, height: 172}; t := reflect.TypeOf(b); //获得匿名字段信息 fmt.Printf("%#v\n", t.Field(0)); //获得匿名字段结构中的字段 //匿名字段A的索引相对B是0,id相对于A的索引是0 fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 0})); //name相对于A的索引是1 fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 1})); //通过反射修改变量的值 c := 6; v := reflect.ValueOf(&c); v.Elem().SetInt(666); fmt.Println(c); //通过反射修改结构中的值 d := C{3, "test3", 33}; v2 := reflect.ValueOf(&d); if v2.Kind() == reflect.Ptr && v2.Elem().CanSet() { v2 = v2.Elem(); //注意这里只有公开字段才可以设置,不然会报错 v2.FieldByName("Name").SetString("哈哈"); } fmt.Println(d); //通过反射动态调用方法 e := C{}; e.Hello("e"); v3 := reflect.ValueOf(&e); m := v3.MethodByName("Hello"); m.Call([]reflect.Value{reflect.ValueOf("eee")}); }
版权声明:博主文章,可以不经博主允许随意转载,随意修改,知识是用来传播的。