go语言特性--反射 青训营

简介: go语言特性--反射 青训营

go语言特性--反射

这篇博客简单总结一下go语言的一个原理--反射。

反射是指在程序运行期间对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。

但是支持反射的语言可以在程序编译期间将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期间获取类型的反射信息,并且有能力修改它们。

1. reflect

任何接口值都是由==类型==和==值==组成的。

反射中类型还区分**类型(type)种类(kind)**两种。

type cat struct{
  // ...
}
// cat 就是类型,而struct是种类
// 种类:struct, 指针, bool, int...

go的反射功能包---reflect

获取类型和具体的值:

// TypeOf()
func f(x interface{}){
  // 获取空接口的具体类型
  v := reflect.TypeOf(x)
  fmt.Printf("%v\n", v)
  // 获取类型和种类
  fmt.Printf("%v, %v\n", v.Name(), v.Kind())
}
////////////////////////////////////////////////////////////////
// ValueOf()
func f(x interface{}){
  // 获取空接口的具体值
  v := reflect.ValueOf(x)
  fmt.Printf("%v\n", v)
  // 获取值得类型和种类
  fmt.Printf("%v\n", v.Kind())
}

通过反射设置值:

func f(x interface{}){
  // 获取空接口的具体值
  v := reflect.ValueOf(x)
  // 取出v的值并修改
  if v.Elem().Kind() == reflect.Int64{
    v.Elem().SetInt(100)
  }
}
func main(){
  var a int64
  a = 10
  // 要传地址
  f(&a)
}

2. 结构体反射

type student struct {
  Name  string `json:"name"`
  Score int    `json:"score"`
}
func main() {
  stu1 := student{
    Name:  "小王子",
    Score: 90,
  }
  t := reflect.TypeOf(stu1)
  fmt.Println(t.Name(), t.Kind()) // student struct
  // 通过for循环遍历结构体的所有字段信息
  for i := 0; i < t.NumField(); i++ {
    field := t.Field(i) 
    fmt.Printf("name:%s index:%d type:%v json tag:%v\n", field.Name, field.Index, field.Type, field.Tag.Get("json"))
  }
  // 通过字段名获取指定结构体字段信息
  if scoreField, ok := t.FieldByName("Score"); ok {
    fmt.Printf("name:%s index:%d type:%v json tag:%v\n", scoreField.Name, scoreField.Index, scoreField.Type, scoreField.Tag.Get("json"))
  }
}

反射可以使得代码更灵活,但是反射也有缺点:

  1. 代码难以理解。
  2. 反射的代码性能很低。

3. 反射应用

获取interface{}空接口类型参数 的具体类型和值。

.ini 配置文件解析器 (所有的配置文件解析都会用到反射)。

json的序列化和反序列化。

4. reflect包的其他用处

// 比较无法直接用 == 比较的类型,如切片
reflect.DeepEqual(a,b)

反射是在C语言中没有的特性,也比较难理解,最好的方法就是在项目实战中去体会理解反射的用处。

相关文章
|
2天前
|
JavaScript Java Go
探索Go语言在微服务架构中的优势
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出。本文将深入探讨Go语言在构建微服务时的性能优势,包括其在内存管理、网络编程、并发模型以及工具链支持方面的特点。通过对比其他流行语言,我们将揭示Go语言如何成为微服务架构中的一股清流。
|
2天前
|
SQL 关系型数据库 MySQL
go语言中安装数据库驱动
【11月更文挑战第1天】
15 5
|
2天前
|
编译器 Go 开发者
go语言中导入相关包
【11月更文挑战第1天】
10 3
|
3天前
|
测试技术 Go
go语言中测试工具
【10月更文挑战第22天】
13 4
|
3天前
|
SQL 关系型数据库 MySQL
go语言中数据库操作
【10月更文挑战第22天】
14 4
|
3天前
|
缓存 前端开发 中间件
go语言中Web框架
【10月更文挑战第22天】
14 4
|
2天前
|
关系型数据库 MySQL 数据库连接
go语言中打开数据库连接
【11月更文挑战第1天】
12 2
|
6天前
|
Go
go语言的复数常量
【10月更文挑战第21天】
24 6
|
6天前
|
Serverless Go
Go语言中的并发编程:从入门到精通
本文将深入探讨Go语言中并发编程的核心概念和实践,包括goroutine、channel以及sync包等。通过实例演示如何利用这些工具实现高效的并发处理,同时避免常见的陷阱和错误。
|
3天前
|
安全 测试技术 Go
Go语言中的并发编程模型解析####
在当今的软件开发领域,高效的并发处理能力是提升系统性能的关键。本文深入探讨了Go语言独特的并发编程模型——goroutines和channels,通过实例解析其工作原理、优势及最佳实践,旨在为开发者提供实用的Go语言并发编程指南。 ####