反射reflect
struct
reflect.TypeOf(i interface{})-->Type
获取结构体的字段的类型,字段名
reflect.ValueOf(i interface{})-->Value
获取结构体的字段的数值
//匿名字段
t1.FieldByIndex([]int{0,0})
v1.FieldByIndex([]int{0,0})
//更改数据
reflect.ValueOf(p1)-->value
reflect.Struct
reflect.ValueOf(&p1)-->value
reflect.Ptr
v1 = v1.Elem()
CanSet()-->bool
c1.FieldByName()-->f1
struct
reflect.TypeOf(i interface{})-->Type
获取结构体的字段的类型,字段名
方法的类型,方法的名字
package main import ( "fmt" "reflect" ) type Person struct { Name string Age int Sex string } func (p Person)Say(msg string) { fmt.Println("hello,",msg) } func (p Person)PrintInfo() { fmt.Printf("姓名:%s,年龄:%d,性别:%s\n",p.Name,p.Age,p.Sex) } func main() { //1.创建一个struct的对象 p1 := Person{"王二狗",30,"男"} //1.第一部分:通过反射操作结构体中的字段:获取字段的类型,名称,数值。。 //通过reflect包下的TypeOf(),获取p1的类型 t1:=reflect.TypeOf(p1) fmt.Println(t1) //main.Person fmt.Println(t1.Name()) //Person fmt.Println(t1.Kind()) //struct //通过reflect包下ValueOf(),获取p1的值 v1:=reflect.ValueOf(p1) //{王二狗 30 男} fmt.Println(v1) //详细操作:判断t1的种类是结构体类型 if t1.Kind() == reflect.Struct{ //获取字段的数量 count:=t1.NumField() //3个字段 fmt.Println(count) for i:=0;i<count;i++{ filed:=t1.Field(i) val:=v1.Field(i).Interface()//根据v1获取对应字段的数值,--->空接口类型 //fmt.Println(filed) fmt.Println("字段名称:",filed.Name,"字段类型:",filed.Type,"字段数值:",val) } } //2.通过反射,操作方法 fmt.Println(t1.NumMethod()) for i:=0;i<t1.NumMethod();i++{ method:=t1.Method(i) fmt.Println(method.Name,method.Type) } //执行方法 m1:=v1.MethodByName("PrintInfo") m1.Call(nil)//执行m1对应的PrintInfo() m2:=v1.MethodByName("Say") m2.Call([]reflect.Value{reflect.ValueOf("你好啊")}) // string-->Value }
reflect.ValueOf(i interface{})-->Value
获取结构体的字段的数值
获取方法的对象--->Call(),执行对应的方法
package main import ( "reflect" "fmt" ) type Animal struct { Name string Age int } type Cat struct { Animal Color string } func main() { c1 := Cat{Animal{"猫咪", 1}, "白色"} t1 := reflect.TypeOf(c1) fmt.Println(t1.NumField()) for i := 0; i < t1.NumField(); i++ { field := t1.Field(i) fmt.Println(field) } //获取匿名字段 /* 匿名字段,可以通过下标获取 FieldByIndex([]int{0})-->Animal FieldByIndex([]int{0,0})-->Animal中的第一个字段:Name */ f1:=t1.FieldByIndex([]int{0,0}) fmt.Println(f1.Name,f1.Type)//Name string f2:=t1.FieldByIndex([]int{0,1}) fmt.Println(f2.Name,f2.Type) v1:=reflect.ValueOf(c1) name:=v1.FieldByIndex([]int{0,0}) fmt.Println(name) }
//匿名字段
t1.FieldByIndex([]int{0,0})
v1.FieldByIndex([]int{0,0})
//更改数据
reflect.ValueOf(p1)-->value
reflect.Struct
reflect.ValueOf(&p1)-->value
reflect.Ptr
v1 = v1.Elem()
CanSet()-->bool
c1.FieldByName()-->f1
f1.SetXXX(新value)
package main import ( "reflect" "fmt" ) type Student struct { Name string Age int School string } func main() { /* 通过反射,来更改对象的数值:前提是数据可以被更改 */ s1:=Student{"王二狗",19,"新东方"} fmt.Printf("%T\n",s1) //main.Student p1:=&s1 fmt.Printf("%T\n",p1) //*main.Student fmt.Println(s1.Name) fmt.Println((*p1).Name,p1.Name) v1:= reflect.ValueOf(&s1) // value if v1.Kind()==reflect.Ptr{ fmt.Println(v1.Elem().CanSet()) v1 = v1.Elem() } f1:=v1.FieldByName("Name") f1.SetString("王三狗") f3:=v1.FieldByName("School") f3.SetString("蓝翔学校") fmt.Println(s1) }