背景
type MyB struct{
Age *int
}
type MyA struct{
Name *string
B *MyB
}
func main() {
a := MyA{}
fmt.Println("a", a) // a {} fmt.Println("a.B", a.B) // a.B // panic: runtime error: invalid memory address or nil pointer dereference fmt.Println("a.B.Age", a.B.Age)
}
在编写 Go 代码中经常会遇到上述层层嵌套的数据结构,比如 Google 的 protobuf 往往有好几层的嵌套。 通常因为业务逻辑的需要这样复杂的结构是必须的,但在编写测试样例时会大大增加开发的负担。因为单元测试只会关心一小部分变量,每次重复的初始化会造成代码的冗余显得很不优雅,所以我们迫切需要一个工具来这类初始化的工作。
事实上 github 已经有了类似的使用反射来实现初始化的项目 allocate ,为了方便大家看懂它的代码,下面我们会由浅入深地介绍相关的知识。
反射是什么?
反射的基本作用是提供了让程序检查数据类型的能力。一个常见的例子就是通过 reflect.TypeOf 方法查看原始数据的类型。在下面的例子中 reflect.TypeOf 可以直接输出变量 x 的原始类型为 MyInt。
type Myint int
func show(x interface{}){
// reflect.TypeOf(x) main.MyInt f