反射介绍
# 1. 反射介绍
Go语言反射(reflection)简述 (opens new window)
反射(reflection)是在Java (opens new window)出现后迅速流行起来的一种概念,通过反射可以获取丰富的类型信息,并可以利用这些类型信息做非常灵活的工作。
大多数现代的高级语言都以各种形式支持反射功能,反射是把双刃剑,功能强大但代码可读性并不理想,若非必要并不推荐使用反射。
# 反射的基本概念
Go语言提供了一种机制在运行时更新和检查变量的值、调用变量的方法和变量支持的内在操作,但是在编译时并不知道这些变量的具体类型,这种机制被称为反射。反射也可以让我们将类型本身作为第一类的值类型处理。
反射是指在程序运行期对程序本身进行访问和修改的能力,程序在编译时变量被转换为内存地址,变量名不会被编译器写入到可执行部分,在运行程序时程序无法获取自身的信息。
支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。
Go语言程序的反射系统无法获取到一个可执行文件空间中或者是一个包中的所有类型信息,需要配合使用标准库中对应的词法、语法解析器和抽象语法树(AST)对源码进行扫描后获得这些信息。
Go语言提供了 reflect 包来访问程序的反射信息。
# 反射可以做什么
反射可以在运行时动态获取变量的各种信息,比如变量的类型,类别等信息
如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)
通过反射,可以修改变量的值,可以调用关联的方法。
使用反射,需要import ("reflect")
# 反射规则可以总结为如下几条:
反射可以将“接口类型变量”转换为“反射类型对象”;
反射可以将“反射类型对象”转换为“接口类型变量”;
如果要修改“反射类型对象”,其值必须是“可写的”。
# reflect 包
自己查文档的方法使用
Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国 (opens new window)
Go语言中的反射是由 reflect 包提供支持的,它定义了两个重要的类型 Type 和 Value 任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value 两部分组成,并且 reflect 包提供了 reflect.TypeOf 和 reflect.ValueOf 两个函数来获取任意对象的 Value 和 Type
reflect.TypeOf(变量名),获取变量的类型,返回reflect.Type类型
reflect.ValueOf(变量名),获取变量的值,返回reflect.Value类型(reflect.Value是一个结构体类型),通过reflect.Value,可以获取到关于该变量的很多信息。