Go语言之反射

Posted haoqirui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言之反射相关的知识,希望对你有一定的参考价值。

变量与反射

1.变量的内在机制

A.类型信息,这部分是元信息,是预先定义好的,比如

  1: var arr [10]int
  2: arr[0] = 10
  3: arr[1] = 20
  4: arr[2] = 30
  5: arr[3] = 40
  6: arr[4] = 50

B.值类型,这部分是程序运行过程中,动态改变的.

  1: type Animal struct {
  2:     Name string
  3:     age int
  4: }
  5: 
  6: var a Animal

2.反射与空接口

A. 空接口可以存储任何类型的变量

B.那么给你一个空接口,怎么知道里面存储的是什么东西

c.在运行时动态的获取一个变量的类型信息和值类型,就叫反射

3.怎么分析

A.内置包 reflect

B.获取类型信息:reflect.TypeOf

C:获取值信息 reflect.ValueOf

 

基本数据类型分析(a是一个空接口变量)

  1: package main
  2: 
  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 string
  3: 	Sex int
  4: 	Age int
  5: }
  6: func main()  {
  7: 	var a student
  8: 	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 student
  3: 	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 string
  3: 	Sex int
  4: 	Age int
  5: }
  6: func (s *Student) SetName(name string)  {
  7: 	s.Name = name
  8: }
  9: func (s *Student) Print() {
 10: 	fmt.Println(s.Name)
 11: }
 12: func main()  {
 13: 	var a Student
 14: 	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.Value
 26: 	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.Value
 35: 	m1.Call(arg2)

结果

  1: method numbers 2
  2: 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 Student
  7: 	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语言之反射的主要内容,如果未能解决你的问题,请参考以下文章

go语言之反射

Go语言基础之反射

Go语言基础之反射

Go语言之反射入门

GO_09:GO语言基础之reflect反射

Go语言之反射