两年前曾经写过一篇博客,是关于反射基本概念的 Go 反射 の 基本概念,之后对其再也没有更深入的学习,主要因为 反射
主要应用在一些基本库中,而在平时的项目开发中几乎用不到。本文结合一个sql构造器的
应用案例,深入的了解一下反射的应用场景。
什么是反射
射就是程序在运行时,能够找到变量类型和值得能力
看到上面的解释,初学的人,就会有疑问,怎么会有这种情况?go
这种强类型的语言,不应该是先把类型定义好了,然后再使用吗?怎么还会有不知道结构体类型的情况呢?你别说,还真有!,请看下面的这样一个例子。
使用反射实现一个SQL构造器
比如我们要设计一个 SQL 构造器,将 student
对象,通过 insertObjectInDb
方法写入到数据库中。
type Student struct {
Name string
Age int
}
func insertObjectInDb(s Student) {
fmt.Printf("把 name: %s 插入数据库\n", s.Name)
fmt.Printf("把 age: %d 插入数据库\n", s.Age)
}
func main() {
s := Student{
Name: "座山雕",
Age: 18,
}
insertObjectInDb(s)
}
通过上面的例子,你就会发现,insertObjectInDb
方法,并不具有普适性。他只能处理 Student
这个固定结构体。如果我再有一个 school
这个结构体呢?他就处理不了。所以该如何提高该方法的泛化能力呢?此时就可以用到反射了
使用反射,泛化 insertObjectInDb 的处理能力
type Student struct {
Name string
Age int
//反射中,不能使用是私有变量,不然会报错
//addr string
}
type School struct {
NumberOfPeople int
Addr string
}
func insertObjectInDb(obj any) {
t := reflect.TypeOf(obj)
v := reflect.ValueOf(obj)
for i := 0; i < t.NumField(); i++ {
fmt.Println("属性名称:", t.Field(i).Name, "属性类型", t.Field(i).Type, "属性值", v.Field(i).Interface())
}
}
func main() {
s := Student{
Name: "座山雕",
Age: 18,
//addr: "北京朝阳区",
}
sc := School{
NumberOfPeople: 3000,
Addr: "上海浦东新区",
}
insertObjectInDb(s)
insertObjectInDb(sc)
}
参考文献
https://juejin.cn/post/7025523426060140551
标签:反射,场景,Name,Age,insertObjectInDb,Student,Go,string From: https://www.cnblogs.com/rush-peng/p/18679695