什么是反射
反射是指程序在运行时能检查其变量和值并找到其类型的能力。
reflect实现了运行时的反射能力,能够让程序操作不同类型的对象,扩展了Go语言的语法元素。
为什么需要反射?
既然程序内部的变量已经有明确的类型和对应的值,那是不是说反射是多此一举呢?当然不是,举一个应用场景:
假设要实现一条SQL语句,根据传入的值,自动拼接成一条完整的SQL语句,例如想要实现一条普适的插入语句:
insert into xxx values (xxx, xxx)
当然可以根据参数来定制不同的insertXXX()
函数,但是这类函数本质上的原理是一致的,只不过根据参数的类型,数量等,最后拼接出来不同的insert语句
这种情况下,使用反射会比较方便:
func creatInsertSQL(i interface{}) string {
// 参数i可以是对应某张表抽象后的结构体
// 使用反射,可以解析出对应的结构体名称以及结构体内各字段的名称及其类型
// 从而使得最终输出形如 `insert into xxx values (xxx, xxx)`的字符串
}
上述过程,就是ORM(Objet Relational Mapping, 对象关系映射)的基本原理。
反射在Go中的应用场景还有很多,诸如IDE 中的代码自动补全功能、对象序列化(encoding/json)、fmt 相关函数的实现等,后续再进行分析。
reflect package
明确了使用反射来实现上述功能,那么,先来看看使用结构体作为参数实现上述类似“自动填充”功能所需要的要素: