当前位置:网站首页>golang6 反射
golang6 反射
2022-06-29 12:47:00 【一只泰迪熊】
反射的基本介绍
1)反射可以在运行时动态获取变量的各种信息, 比如变量的类型(type),类别(kind)
2)如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)
3)通过反射,可以修改变量的值,可以调用关联的方法。
4)使用反射,需要 import (“reflect”)
反射重要的函数和概念
//专门演示反射
func reflectTest01(b interface{
}) {
//通过反射获取的传入的变量的 type , kind, 值
//1. 先获取到 reflect.Type
rTyp := reflect.TypeOf(b)
fmt.Println("rType=", rTyp)
//2. 获取到 reflect.Value
rVal := reflect.ValueOf(b)
n2 := 2 + rVal.Int()
//n3 := rVal.Float()
fmt.Println("n2=", n2)
//fmt.Println("n3=", n3)
fmt.Printf("rVal=%v rVal type=%T\n", rVal, rVal)
//下面我们将 rVal 转成 interface{}
iV := rVal.Interface()
//将 interface{} 通过断言转成需要的类型
num2 := iV.(int)
fmt.Println("num2=", num2)
}
//专门演示反射[对结构体的反射]
func reflectTest02(b interface{
}) {
//通过反射获取的传入的变量的 type , kind, 值
//1. 先获取到 reflect.Type
rTyp := reflect.TypeOf(b)
fmt.Println("rType=", rTyp)
//2. 获取到 reflect.Value
rVal := reflect.ValueOf(b)
//3. 获取 变量对应的Kind
//(1) rVal.Kind() ==>
kind1 := rVal.Kind()
//(2) rTyp.Kind() ==>
kind2 := rTyp.Kind()
fmt.Printf("kind =%v kind=%v\n", kind1, kind2)
//下面我们将 rVal 转成 interface{}
iV := rVal.Interface()
fmt.Printf("iv=%v iv type=%T \n", iV, iV)
//将 interface{} 通过断言转成需要的类型
//这里,我们就简单使用了一带检测的类型断言.
//同学们可以使用 swtich 的断言形式来做的更加的灵活
stu, ok := iV.(Student)
if ok {
fmt.Printf("stu.Name=%v\n", stu.Name)
}
}
type Student struct {
Name string
Age int
}
type Monster struct {
Name string
Age int
}
func main() {
//请编写一个案例,
//演示对(基本数据类型、interface{}、reflect.Value)进行反射的基本操作
//1. 先定义一个int
var num int = 100
reflectTest01(num)
//2. 定义一个Student的实例
stu := Student{
Name : "tom",
Age : 20,
}
reflectTest02(stu)
}
反射的注意事项和细节
1)reflect.Value.Kind,获取变量的类别,返回的是一个常量
2)Type 和 Kind 的区别 Type 是类型, Kind 是类别,
Type 和 Kind 可能是相同的,也可能是不同的.
比如: var num int = 10 num 的 Type 是 int , Kind 也是 int
比如: var stu Student stu 的 Type 是 pkg1.Student , Kind 是 struct
5)通过反射的来修改变量, 注意当使用 SetXxx 方法来设置需要通过对应的指针类型来完成, 这样才能改变传入的变量的值, 同时需要使用到 reflect.Value.Elem()方
6)reflect.Value.Elem()
反射最佳实践
1)使用反射来遍历结构体的字段,调用结构体的方法,并获取结构体标签的值
//定义了一个Monster结构体
type Monster struct {
Name string `json:"name"`
Age int `json:"monster_age"`
Score float32 `json:"成绩"`
Sex string
}
//方法,返回两个数的和
func (s Monster) GetSum(n1, n2 int) int {
return n1 + n2
}
//方法, 接收四个值,给s赋值
func (s Monster) Set(name string, age int, score float32, sex string) {
s.Name = name
s.Age = age
s.Score = score
s.Sex = sex
}
//方法,显示s的值
func (s Monster) Print() {
fmt.Println("---start~----")
fmt.Println(s)
fmt.Println("---end~----")
}
func TestStruct(a interface{
}) {
//获取reflect.Type 类型
typ := reflect.TypeOf(a)
//获取reflect.Value 类型
val := reflect.ValueOf(a)
//获取到a对应的类别
kd := val.Kind()
//如果传入的不是struct,就退出
if kd != reflect.Struct {
fmt.Println("expect struct")
return
}
//获取到该结构体有几个字段
num := val.NumField()
fmt.Printf("struct has %d fields\n", num) //4
//变量结构体的所有字段
for i := 0; i < num; i++ {
fmt.Printf("Field %d: 值为=%v\n", i, val.Field(i))
//获取到struct标签, 注意需要通过reflect.Type来获取tag标签的值
tagVal := typ.Field(i).Tag.Get("json")
//如果该字段于tag标签就显示,否则就不显示
if tagVal != "" {
fmt.Printf("Field %d: tag为=%v\n", i, tagVal)
}
}
//获取到该结构体有多少个方法
numOfMethod := val.NumMethod()
fmt.Printf("struct has %d methods\n", numOfMethod)
//var params []reflect.Value
//方法的排序默认是按照 函数名的排序(ASCII码)
val.Method(1).Call(nil) //获取到第二个方法。调用它
//调用结构体的第1个方法Method(0)
var params []reflect.Value //声明了 []reflect.Value
params = append(params, reflect.ValueOf(10))
params = append(params, reflect.ValueOf(40))
res := val.Method(0).Call(params) //传入的参数是 []reflect.Value, 返回[]reflect.Value
fmt.Println("res=", res[0].Int()) //返回结果, 返回的结果是 []reflect.Value*/
}
func main() {
//创建了一个Monster实例
var a Monster = Monster{
Name: "黄鼠狼精",
Age: 400,
Score: 30.8,
}
//将Monster实例传递给TestStruct函数
TestStruct(a)
}
边栏推荐
- 【毕业季】这四年一路走来都很值得——老学长の忠告
- 维修记录导出的excel表格太大怎么办?
- Introduction to esp8266: three programming methods "suggestions collection"
- System. Currenttimemillis() and system Nanotime() which is faster? Most people get the wrong answer!
- Exploring the way of automated testing - Preparation
- Open source machine learning platform
- Follow me study hcie big data mining Chapter 1 Introduction to data mining module 1
- [document translation] camouflaged object detection
- Hash hash game system development explanation technology -- hash game system development solution analysis
- Summary of common MySQL statements and commands
猜你喜欢

丢弃 Tkinter!简单配置快速生成超酷炫 GUI!

Autonomous and controllable city! Release of the first domestic artiq architecture quantum computing measurement and control system
![[untitled] error in installation dependency: refusing to install package with name](/img/53/8c871037b7586343fd509dcecb0d96.png)
[untitled] error in installation dependency: refusing to install package with name "* * *" under a package

windows平台下的mysql启动等基本操作

Ordinary users use vscode to log in to SSH and edit the root file

思科模拟器简单校园网设计,期末作业难度

Leetcode question brushing: String 07 (repeated substring)

mysql函数和约束

Openssl证书工具使用手册

How to make dapper support dateonly type
随机推荐
昨天面试居然聊了半个多小时的异常处理
C language simulation to realize all character functions
How to install MySQL 8.0 on rocky Linux and almalinux
Problems in replacing RESNET convolution of mmdet with ghost convolution group
Cloud native (31) | kubernetes chapter kubernetes platform basic pre installed resources
mysql函数和约束
##Mondo Rescue制作镜像文件(有利于镜像损坏恢复)
Write a shell script to find the "reverse order" of a number“
直觉与实现:Batch Normalization
从Mpx资源构建优化看splitChunks代码分割
【毕业季·进击的技术er】1076万毕业生,史上最难就业季?卷又卷不过,躺又躺不平,敢问路在何方?
#yyds干货盘点# 解决剑指offer:在二叉树中找到两个节点的最近公共祖先
win32版俄罗斯方块(学习MFC必不可少)
C language__ VA_ ARGS__ Usage of
请问老师炒期货怎么设定安全线和安全边际?
机器学习 Out-of-Fold 折外预测详解 | 使用折外预测 OOF 评估模型的泛化性能和构建集成模型
[untitled] error in installation dependency: refusing to install package with name "* * *" under a package
php-fpm 启动参数及重要配置详解
ANSVC无功补偿装置在河北某购物广场中的应用
存算一体为何是造芯新方向?|对撞派 x 知存科技