一: 反射
1 反射是指在程序运行期对程序本身进行访问和修改的能力 2 go程序在运行期使用reflect包访问程序的反射信息
1查看类型、字段和方法
package main import ( "fmt" "reflect" ) //结构体 type User struct { Id int Name string Age int } //绑定方法 func (u User) Hello() { fmt.Println("Hello User!") } //反射操作 func Info(o interface{}) { //获取目标对象信息 t := reflect.TypeOf(o) //获取Name,也就是对象类型 fmt.Println("传入的对象类型:", t.Name()) //获取对象的值信息 v := reflect.ValueOf(o) fmt.Println("字段:===========================") //遍历出所有字段 //NumField()获取对象有几个字段 for i := 0; i < t.NumField(); i++ { //取每个字段 f := t.Field(i) //通过interface()可以取具体字段对应的值 val := v.Field(i).Interface() fmt.Printf("%s:%v=%v ", f.Name, f.Type, val) } fmt.Println("方法:============================") for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) fmt.Printf("%s:%v ", m.Name, m.Type) } } func main() { u := User{1, "Mr.Sun", 18} Info(u) }
2查看匿名字段
package main import ( "reflect" "fmt" ) //结构体 type User struct { Id int Name string Age int } type Boy struct { User Addr string } func main() { m := Boy{User{1,"zhangsan",20},"sz"} //获取对象信息 t := reflect.TypeOf(m) //#号会把反射的结构体的详情打印 fmt.Printf("%#v ",t.Field(0)) }
3 修改基本类型的值
package main import ( "fmt" "reflect" ) func main() { x :=123 v :=reflect.ValueOf(&x) v.Elem().SetInt(666) fmt.Println(x) }
4 修改结构体的值
package main import ( "reflect" "fmt" ) //结构体 type User struct { Id int Name string Age int } //反射修改结构体的值 func SetValue(o interface{}) { //获取值类型 v := reflect.ValueOf(o) //获取指针指向的元素 v = v.Elem() //修改User的Name f := v.FieldByName("Name") //Kind()是判断字段类型 if f.Kind() == reflect.String { f.SetString("wangwu") } } func main() { u := User{1, "lisi", 22} SetValue(&u) fmt.Println(u) }
5 调用方法
package main import ( "reflect" "fmt" ) //结构体 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, "lisi", 22} //获取对象值信息 v := reflect.ValueOf(u) //通过方法名字,取到具体方法 m := v.MethodByName("Hello") //设置方法参数 args := []reflect.Value{reflect.ValueOf("wangwu")} //调用方法 m.Call(args) }