这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记。
反射的定义
反射是指,计算机程序在运行时,可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是在程序运行时能够观察并且修改自己的行为。
GO语言提供了一种机制在运行时更新变量和检查他们的值、调用他们的方法。但是在编译时并不知道这些变量的具体类型,这成为“反射机制”。
在reflect包里定义了一个接口和一个机构体,即reflect.Type接口和reflect.Value机构体,她们提供很多函数来获取存储在借口里的类型信息。
- reflect.Type接口主要提供关于类型相关的信息
- reflect.Value结构体主要提供关于值相关的信息,可以获取甚至改变类型的值
func TypeOf(i interface()) Type
func ValueOf(i interface()) VAlue
TypeOf()函数用来提取一个接口中值的类型信息。由于它的输入参数是一个空的interface{},所以在调用此函数时,实参会先被转化为interface{}类型。这样,实参的类型信息、方法集、值信息都存储到interface{}变量里了。
反射的三大法则
- 反射可以将“接口类型变量”转换为“反射类型对象”
- 反射可以将“反射类型对象”转换为“接口类型变量”
- 如果要修改“反射类型对象”,则其值必须是“可写的”
下面给出事例代码(其中之一)
package main
iomport (
"fmt"
"reflect"
)
fuc main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
}
反射中的一些常用方法
func (v Value) setBool(x bool)
func (v Value) setBytes(x []byte)
func (v Value) setFloat(x float64)
func (v Value) setInt(x int64)
func (v Value) setString(x int64)
反射的规则里需要注意以下几点
- 不是接受变量指针创建的反射对象,是不具备“可写性”的
- 是否具备“可写性”可使用CanSet()方法来得知
- 创建反射对象时传入变量的是指针
- 使用Elem()方法返回指针指向的数据