浅谈Go语言反射
2023-09-11 14:16:33 时间
1 为什么需要反射
反射是框架的灵魂。
反射(Reflection)其实是通过允许在运行时存取程序数据,以改变程序行为的程序设计技术。也就是说,反射可以帮助我们将动态的功能实现或调用变为静态的功能描述。
反射有优点就是可以让程序灵活,更新和维护都更加简单方便,但是反射并不是没有缺点,反射在执行时对于CPU和内存资源会进行占用。
2 Go反射的使用
2.1 针对结构体的反射
type Student struct {
Id int64
Name string
Age int
}
func TestStruct(t *testing.T) {
stu := Student{1, "zs", 12}
obj := reflect.ValueOf(stu)
field := obj.FieldByName("Name")
field1 := obj.Field(0)
num := obj.NumField()
fmt.Println("字段数量:", num)
fmt.Println("Name字段的值:", field)
fmt.Println("第0个字段的值:", field1)
obj1 := reflect.ValueOf(new(Student))
addr := obj1.CanAddr() //是否能寻址
if addr {
fmt.Println(obj1.Addr())
}
}
2.2 针对常见数据结构的反射
// 切片类型的反射
func TestSlice(t *testing.T) {
slice := make([]int, 10)
s := reflect.ValueOf(slice)
//加入元素
s.Index(0).Set(reflect.ValueOf(100))
//获取元素
i := s.Index(0).Interface()
fmt.Println(slice)
fmt.Println(i)
}
// Map类型的反射
func TestMap(t *testing.T) {
m := make(map[string]interface{})
m["A"] = 1
m["B"] = 2
m["C"] = 3
mv := reflect.ValueOf(m)
//赋值
mv.SetMapIndex(reflect.ValueOf("D"),reflect.ValueOf(4))
iter := mv.MapRange()
keys := mv.MapKeys()
fmt.Println(keys)
for iter.Next() {
fmt.Println(iter.Value())
}
}
3 小总结
反射在架构中扮演者很重要的作用,其中最重要的就是增强架构的抽象,Go语言反射里最重要的两个概念是Type和Value,Type用于获取类型相关的信息(比如slice的长度,Struct的成员,函数的参数),Value用于获取和修改原始数据的值(比如修改slice和map中的元素,修改Struct的成员变量)。
参考:
https://zhuanlan.zhihu.com/p/411313885
相关文章
- Go 语言如何读取 excel 测试数据,简单易学
- Golang 【basic_leaming】go mod 以及包详解
- The "Go" Learning Trip -- 2. Go Basics -- Part1-2
- Go程序设计语言1.7 一个Web服务器
- Go程序设计语言2.2 声明
- Go程序设计语言2.4 赋值
- Go程序设计语言3.2 浮点数
- 如何在 Docker 中设置 Go 并部署应用
- Go分布式爬虫笔记(二十二)
- Go-MySQL-Driver,让Go语言拥抱MySQL
- 深入浅出Go语言通道chan类型
- Go语言中的单引号、双引号、反引号
- Eclipse配置开发Go的插件——Goclipse
- Go基础系列:函数(2)——回调函数和闭包
- Go基础系列:构建go程序
- GO语言练习:反射
- GO语言练习:不定参数函数
- 初识GO语言——安装Go语言
- Go语言学习(二)
- protoc-gen-go: unable to determine Go import path for "xxx.proto"
- 8.Go-Reader,Writer和ioutil
- 安卓破解版Pokémon Go?DroidJack木马开始蔓延
- GO语言基础之reflect反射
- Go语言学习:Day 2——初识Go语言