反射
反射可以干什么
- 反射可以再运行时动态获取变量的各种信息,比如变量的类型,类别等信息
- 如果是结构体变量,还可以获取到结构体的信息(包括结构体的字段和方法)
- 通过反射,可以修改变量的值,可以调用变量的方法
- 使用放射需要引用
import "reflect"
反射的相关函数
reflect.TypeOf(变量名)
,获取变量的类型,返回reflect.Type类型
reflect.ValueOf(变量名)
,获取变量的值,返回reflect.Value类型(reflect.Value是一个结构体类型),通过reflect.Value,可以获取到关于该
变量的很多信息.
- 上面的变量名的类型为空接口
将一个int类型转换为反射的reflect.Value类型 再将reflect.Value转换为基本数据类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import ( "fmt" "reflect" )
func testRelfert(n interface{}) { reType := reflect.TypeOf(n) fmt.Println("reType:", reType) fmt.Printf("reType的类型是:%T \n", reType) reValue := reflect.ValueOf(n) fmt.Println("vaType:", reValue) fmt.Printf("这个函数中的类型:%T \n", reValue) var num1 int64 = 10 num2 := reValue.Int() fmt.Println("int求和:", num1+num2) i2 := reValue.Interface() integer := i2.(int) fmt.Printf("n的类型为:%T,n的值为:%v \n", integer, integer) } func main() { var num int = 10 fmt.Println(num) testRelfert(num) fmt.Println("exit...") }
|
对结构体进行反射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import ( "fmt" "reflect" ) func testRelfert(s interface{}) { reType := reflect.TypeOf(s) fmt.Println("reType:", reType) reValue := reflect.ValueOf(s) fmt.Println("reValue:", reValue) fmt.Printf("reValue结构体反射的类型:%T,值为:%v \n", reValue.String(), reValue.String()) val := reValue.Interface() v, flag := val.(Jiegouti) if flag { fmt.Println("结构体的值:", v.Name) } }
type Jiegouti struct { Name string } func main() { j := Jiegouti{} j.Name = "Gary Wang" var num int = 10 fmt.Println(num) testRelfert(j) fmt.Println("exit...") }
|
获取变量的类别
两种方式:
- reflect.TypeOf.Kind()
- reflect.ValueOf.Kind()
Kind的值是常量值:type Kind uint
1 2 3 4 5 6 7 8 9 10 11
| func testRelfert(s interface{}) { reType := reflect.TypeOf(s) reValue := reflect.ValueOf(s) k1 := reType.Kind() k2 := reValue.Kind() fmt.Println(k1, k2) }
|
反射修改变量的值
基本数据类型:
1 2 3 4 5 6 7 8 9 10 11
| func testRelfert(s interface{}) { reValue := reflect.ValueOf(s) reValue.Elem().SetInt(100) } func main() { var num int = 10 testRelfert(&num) fmt.Println(num) fmt.Println("exit...") }
|
通过反射操作结构体的属性和方法
1.调用结构体的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| type Student struct { Name string Age int } func (s Student) Play(a int, b int) int { fmt.Println("play func :", a+b) return a + b } func testRelfert(s interface{}) { reValue := reflect.ValueOf(s) fmt.Println(reValue) n1 := reValue.NumField() fmt.Println(n1) for i := 0; i < n1; i++ { fmt.Printf("第%d个字段的值是:%v \n", i, reValue.Field(i)) } n2 := reValue.NumMethod() fmt.Println(n2) for i := 0; i < n2; i++ { fmt.Printf("第%d的方法是:%v \n", i, reValue.Method(i)) reValue.Method(i).Call(nil) var params []reflect.Value params = append(params, reflect.ValueOf(10)) params = append(params, reflect.ValueOf(20)) res := reValue.Method(i).Call(params) fmt.Println(res[0].Int()) } } func main() { s := Student{ Name: "Gary Wang", Age: 18, } testRelfert(s) fmt.Println("exit...") }
|
2.修改结构体的字段值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| type Student struct { Name string Age int } func testRelfert(s interface{}) { reValue := reflect.ValueOf(s) n1 := reValue.Elem().NumField() fmt.Println("获取到字段的个数:", n1) reValue.Elem().Field(0).SetString("张三") } func main() { s := Student{ Name: "Gary Wang", Age: 18, } testRelfert(&s) fmt.Println(s) fmt.Println("exit...") }
|