简介
- 反射是程序运行时动态地调用对象的方法和属性
- 引用包:
import (
"reflect"
)
- 常用方法: reflect.TypeOf() 和reflect.ValueOf()
reflect.ValueOf()用来获取输入参数接口中的数据的值,如果接口为空则返回0
reflect.TypeOf()用来动态获取输入参数接口中的值的类型,如果接口为空则返回nil
基本使用
var a = 3
// 获取变量的类型,返回reflect.Type类型
fmt.Println("类型:", reflect.TypeOf(a))
//获取变量的值,返回reflect.Value类型
v := reflect.ValueOf(a)
fmt.Println("值:", v)
fmt.Println("类型:", v.Type())
//获取变量的类别,返回一个常量
fmt.Println("类型常量", v.Kind())
//转换成interface{}类型
fmt.Println("值:", v.Interface())
输出结果:
类型: int
值: 3
类型: int
类型常量 int
值: 3
结构体
- TypeOf和ValueOf
// 定义一个Product
type Product struct {
Name string `json:"prod_name"`
Stock int `json:"stock"`
}
var prod = Product{
Name: "iphone8",
Stock: 5,
}
prodV := reflect.ValueOf(prod)
fmt.Println("类型:", reflect.TypeOf(prod))
fmt.Println("值:", prodV)
fmt.Println("类型常量:", prodV.Kind())
fmt.Println("值:", prodV.Interface())
输出结果:
类型: main.Product
值: {iphone8 5}
类型常量: struct
值: {iphone8 5}
- 使用Elem获取指针指向的变量
val := reflect.ValueOf(prod)
fields := val.NumField()
fmt.Println("字段数=:", fields)
for i := 0; i < fields; i++ {
fmt.Printf("第%d个类型为%s,值为%v\n", i, val.Field(i).Kind(), val.Field(i))
}
输出结果:
字段为数: 2
第0个类型为string,值为iphone8
第1个类型为int,值为5
- 获取tag
val := reflect.ValueOf(prod)
fields := val.NumField()
prodT := reflect.TypeOf(prod)
for i := 0; i < fields; i++ {
tag := prodT.Field(i).Tag.Get("json")
fmt.Printf("第%d个,json值=%s\n", i, tag)
}
输出结果为:
第0个,json值=prod_name
第1个,json值=stock
s := reflect.ValueOf(&prod).Elem()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("名称=%s, 类型=%s, 值=%v\n", s.Type().Field(i).Name, f.Type(), f.Interface())
}
输出结果:
名称=Name, 类型=string, 值=iphone8
名称=Stock, 类型=int, 值=5
- 设置值
s.Field(0).SetString("iphoneX")
s.Field(1).SetInt(1)
fmt.Println("修改后:", prod)
输出结果:
修改后: {iphoneX 1}