Go语言之反射
Posted haoqirui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言之反射相关的知识,希望对你有一定的参考价值。
变量与反射
1.变量的内在机制
A.类型信息,这部分是元信息,是预先定义好的,比如
1: var arr [10]int
2: arr[0] = 103: arr[1] = 204: arr[2] = 305: arr[3] = 406: arr[4] = 50
B.值类型,这部分是程序运行过程中,动态改变的.
1: type Animal struct {
2: Name string3: age int
4: }5:6: var a Animal
2.反射与空接口
A. 空接口可以存储任何类型的变量
B.那么给你一个空接口,怎么知道里面存储的是什么东西
c.在运行时动态的获取一个变量的类型信息和值类型,就叫反射
3.怎么分析
A.内置包 reflect
B.获取类型信息:reflect.TypeOf
C:获取值信息 reflect.ValueOf
基本数据类型分析(a是一个空接口变量)
打印1: package main2:3: import (4: "fmt"
5: "reflect"
6: )7:8: func reflect_example(a interface{}) {9: t := reflect.TypeOf(a)10: fmt.Printf("type of a: %v ", t)
11: }12:13: func main() {14: var x float64 = 3.4
15: reflect_example(x)16: var y float32 = 3.2
17: reflect_example(y)18: }
1: type of a: float64
2: type of a: float32
t.Kind()直接获取类型,结果为reflect.Int64,reflect.String等…可以用swtich来判断
reflect.ValueOf获取变量的值相关信息:
1: var x float64 = 3.4
2: v := reflect.ValueOf(x)3: // 和reflect.TypeOf功能是一样的
4: fmt.Println("type:", v.Type())
5: fmt.Println("kind is float64:", v.kind()==reflect.Float64)
6:7: fmt.Println("value:", v.Float())
通过反射设置变量的值
1: func reflect_set_value(a interface{}){2: t := reflect.ValueOf(a)3: k := t.Kind()4: switch k {
5: case reflect.Int64:
6: t.SetInt(100)7: fmt.Println("typeof is int64")
8: case reflect.Float64:
9: t.SetFloat(6.6)10: fmt.Println("typeof is Float64")
11: case reflect.Ptr:
12: //t.Elem()等同于*t
13: t.Elem().SetFloat(6.6)14: }15: }16: func main() {17: var x float64 = 9.9
18: // 注意这里传入的是x的指针
19: reflect_set_value(&x)20: fmt.Println("x value:",x)
21: }
结构体反射
获取结构体类型相关信息
1: type student struct {
2: Name string3: Sex int
4: Age int
5: }6: func main() {7: var a student8: v := reflect.ValueOf(a)9: t := v.Type()10: // t := reflect.TypeOf(a)
11: kind := t.Kind()12: switch kind {
13: case reflect.Int64:
14: fmt.Println("")15: case reflect.Float64:
16: fmt.Println("")17: case reflect.Struct:
18: fmt.Println("is struct")
19: fmt.Println("field num", v.NumField())
20: for i:=0;i<v.NumField();i++ {
21: field := v.Field(i)22: fmt.Printf("name-%s, type-%v value-%v ", t.Field(i).Name, field.Type(), field.Interface())
23: }24: }
设置结构体字段的值
1: func main() {2: var a student3: v := reflect.ValueOf(&a)4: v.Elem().Field(0).SetString("stu01")
5: v.Elem().FieldByName("Sex").SetInt(2)
6: v.Elem().FieldByName("Age").SetInt(18)
7: fmt.Println("a:", a)
结构体方法调用
1: type Student struct {
2: Name string3: Sex int
4: Age int
5: }6: func (s *Student) SetName(name string) {7: s.Name = name8: }9: func (s *Student) Print() {10: fmt.Println(s.Name)11: }12: func main() {13: var a Student14: v := reflect.ValueOf(&a)15: t := v.Type()16:17: // 获取方法的具体信息
18: fmt.Println("method numbers", t.NumMethod())
19: for i:=0; i<t.NumMethod();i++ {
20: method := t.Method(i)21: fmt.Printf("name:%s type:%s ", method.Name, method.Type)
22: }23: // 有参数的方法
24: m := v.MethodByName("SetName")
25: var arg1 []reflect.Value26: name := "stu1"
27: // 将string转化成reflect.Value类型
28: nameVal := reflect.ValueOf(name)29: arg1 = append(arg1, nameVal)30: m.Call(arg1)31:32: // 无参数的方法
33: m1 := v.MethodByName("Print")
34: var arg2 []reflect.Value35: m1.Call(arg2)
结果
1: method numbers 22: name:Print type:func(*main.Student)3: name:SetName type:func(*main.Student, string)4: stu1
tag信息获取
1: type Student struct {
2: Name string `json:"name"`
3: }4:5: func main() {6: var a Student7: v := reflect.ValueOf(&a)8: t := v.Type()9: field0 := t.Elem().Field(0)10: fmt.Println("tag json =",field0.Tag.Get("json"))11: }
总结
反射就是在运行程序中可以动态地获取一个变量的类型信息和值信息
以上是关于Go语言之反射的主要内容,如果未能解决你的问题,请参考以下文章