Go之路(十九):反射
反射
反射主要是可以动态获取变量以及可以对变量进行很多操作
例子:
package main import( "fmt" "reflect" ) type Student struct{ Name string Age int } func test1(a interface{}){ // 把a转换成reflect.value类型,可以有许多操作 fmt.Println(reflect.TypeOf(a)) v := reflect.ValueOf(a) fmt.Println(reflect.TypeOf(v)) fmt.Println(v) k := v.Kind() fmt.Println(k) t := v.Type() fmt.Println(t) } func main() { var a = Student{ Name:"tom", Age : 13, } test1(a) }
另外,当传入指针进入的时候,需要用a.Elem()来获取变量的值,如果不这样做 会报错
例如:
package main import( "fmt" "reflect" ) type Student struct{ Name string Age int } func test1(a interface{}){ v := reflect.ValueOf(a) v.SetInt(100) } func main() { var a int = 100 test1(a) fmt.Println(a) }
结果:
传入指针时,需要加上Elem()方法才能获取到指针所指的变量(因为反射的这些类型不支持*号操作)
package main import( "fmt" "reflect" ) type Student struct{ Name string Age int } func test1(a interface{}){ v := reflect.ValueOf(a) v.Elem().SetInt(100) } func main() { var a int = 100 test1(&a) fmt.Println(a) }
另外,还可以对值的方法,字段等进行操作
但是如果结构体内的方法名称是小写的话是获取不到的
package main import( "fmt" "reflect" ) type Student struct{ Name string Age int } func (self Student)Test(){ fmt.Println("i am the test") } func (self Student)Test2(){ fmt.Println("i am the test") } func test1(a interface{}){ v := reflect.ValueOf(a) kd := v.Kind() fmt.Println(kd) if kd != reflect.Struct{ fmt.Println("请传入正确的类型") } fileds := v.NumField() fmt.Println(fileds) methods := v.NumMethod() fmt.Println(methods) for i:=0;i<fileds;i++{ fmt.Println(v.Field(i)) } } func main() { var a = Student{ Name:"tom", Age:12, } test1(a) fmt.Println(a) }