go 继承模型下 无限反射父级
下面摘取go-tool中模型解析select *的源码
// 层级递增解析tag
func GetReflectTag(reflectType reflect.Type, buf *bytes.Buffer) {
if reflectType.Kind() != reflect.Struct {
return
}
for i := 0; i < reflectType.NumField(); i++ {
tag := reflectType.Field(i).Tag.Get("json")
if tag == "" {
GetReflectTag(reflectType.Field(i).Type, buf)
continue
}
buf.WriteString("`")
buf.WriteString(tag)
buf.WriteString("`,")
}
}
// 根据model中表模型的json标签获取表字段
// 将select* 变为对应的字段名
func GetColSQL(model interface{}) (sql string) {
var buf bytes.Buffer
typ := reflect.TypeOf(model)
for i := 0; i < typ.NumField(); i++ {
tag := typ.Field(i).Tag.Get("json")
if tag == "" {
GetReflectTag(typ.Field(i).Type, &buf)
//Logger().Println(reflectType.Field(i).Tag.Get("json"))
//Logger().Println(reflectType.NumField())
//Logger().Println(GetColSQL(reflectType))
continue
}
// sql += "`" + tag + "`,"
buf.WriteString("`")
buf.WriteString(tag)
buf.WriteString("`,")
}
sql = string(buf.Bytes()[:buf.Len()-1]) //去掉点,
return sql
}
-
来看上面源码发生了什么
1.通过反射得到模型的reflect.Type进行模型外层解析
2.解析过程判断是否存在上级struct
3.对父级struct的reflect.Type递归解析 -
运行测试
func TestExtends(t *testing.T) {
type UserDe struct {
User
Other string `json:"other"`
}
type UserDeX struct {
a []string
UserDe
OtherX string `json:"other_x"`
}
type UserMore struct {
UserDeX
ShopName string `json:"shop_name"`
}
t.Log(GetColSQL(UserDeX{}))
//t.Log(GetMoreTableColumnSQL(UserMore{}, []string{"user","shop"}[:]...))
}
// output
=== RUN TestExtends
--- PASS: TestExtends (0.00s)
db_test.go:301: `id`,`name`,`createtime`,`other`,`other_x`
PASS
ps: 不直接进行一个函数的递归, 是由于反射后的对象, 是reflect相关类型, 不是model interface{}内部接收的类型了