• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go语言之反射

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

变量与反射

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\n", 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\n", 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\n", 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: }

总结

反射就是在运行程序中可以动态地获取一个变量的类型信息和值信息


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
[go]接口型函数分析发布时间:2022-07-10
下一篇:
Go语言基础之数组发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap