存储 information/reference 左右结构
Store information/reference about structure
我正在寻找一种方法来存储结构函数应该使用的信息。每个结构体对应某个数据库table.
type Record struct {
TableName string
PrimaryKey string
//XormStruct // how can I store User or Post here?
XormStruct2 interface{} // see I have tried below
XormStruct3 reflect.Type // see I have tried below
}
var posts []Post
var ListOfTables [...]Record {
{"User", "id", User},
//{"Post", "post_id", Post},
{"Post", "post_id", posts, reflect.TypeOf([]Post{})},
}
// User is xorm struct
type User struct {
Id int64
Name string
}
// Post is xorm struct
type Post struct {
Post_id int64
Name string
Other string
}
我希望能够为 table 动态选择结构。
for _, rec := range ListOfTables {
//var entries []rec.XormStruct // this does not work, of course
//var entries []reflect.TypeOf(rec.XormStruct) // this does not work either
// xorm is *xorm.Engine
xorm.Find(&entries)
//xorm.Find(&rec.XormStruct2) //with interface{}, does not work - produces an empty &[]
posts3 := reflect.New(rec.XormStruct3).Interface()
//xorm.Find(&posts3) // same as above, produces empty &[]
var posts []Post
xorm.Find(&posts) // produces desired data
// afterwards I will do same to any table entries, e.g.
xml.Marshal(entries)
// so there is really no need to create identical functions for each table
}
目标 DRY(我有大约 30 tables,功能相同)
我试过:
要用reflect.TypeOf()
,但是我看不懂if/how我可以用它(reflect.Type
)定义一个新的变量
用 XormStruct interface{}
定义记录并为每个 ListOfTables 条目创建一个切片,例如var posts []Post
和 {"Post", "post_id", posts},
正在搜索 SO 和 godocs
在我看来,xorm.Find()
并不是 "happy" 获得 interface{}
而不是 []Posts
,即使它没有这么说。
更新:
我相信最大的区别是:
spew.Dump(posts3) //posts3 := reflect.New(rec.XormStruct3).Interface()
// (*[]main.Post)<0x2312312>(<nil>)
spew.Dump(posts) //var posts []Post
// ([]main.Post)<nil>
解决方案
posts3 := reflect.New(rec.XormStruct3).Interface()
xorm.Find(posts3) // not &posts3
可以使用reflect.Type
to represent / describe a Go type. And at runtime, you may use reflect.New()
to obtain a pointer to the zeroed value of this type wrapped in a reflect.Value
. And if you need a slice instead of a single value, you may use reflect.SliceOf()
,或者先获取切片值的类型描述符
如果您存储表的 refect.Type
个值,您可以这样使用它:
type Record struct {
TableName string
PrimaryKey string
XormStruct reflect.Type
}
var ListOfTables [...]Record {
{"User", "id", reflect.TypeOf((*User)(nil)).Elem()},
{"Post", "post_id", reflect.TypeOf((*Post)(nil)).Elem()},
}
// User is xorm struct
type User struct {
Id int64
Name string
}
// Post is xorm struct
type Post struct {
Post_id int64
Name string
Other string
}
注意你必须使用导出字段!
然后处理表格:
for _, rec := range ListOfTables {
entries := reflect.New(reflect.SliceOf(t.XormStruct)).Interface()
err := xorm.Find(entries)
// Handle error
err := xml.Marshal(entries)
// Handle error
}
您可以使用 JSON 查看此的工作示例(概念证明)(没有 xorm
,因为它在 Go Playground 上不可用):Go Playground.
如果您首先要存储切片的 reflect.Type
个值:
var ListOfTables [...]Record {
{"User", "id", reflect.TypeOf([]User{})},
{"Post", "post_id", reflect.TypeOf([]Post{})},
}
而且使用起来也更简单:
for _, rec := range ListOfTables {
entries := reflect.New(t.XormStruct).Interface()
err := xorm.Find(entries)
// Handle error
err := xml.Marshal(entries)
// Handle error
}
查看此概念的证明:Go Playground。
请注意,如果 Record
包含切片类型(在字段 XormStruct
中),如果您需要访问结构的类型(结构的元素类型),您可以使用Type.Elem()
为此。
我正在寻找一种方法来存储结构函数应该使用的信息。每个结构体对应某个数据库table.
type Record struct {
TableName string
PrimaryKey string
//XormStruct // how can I store User or Post here?
XormStruct2 interface{} // see I have tried below
XormStruct3 reflect.Type // see I have tried below
}
var posts []Post
var ListOfTables [...]Record {
{"User", "id", User},
//{"Post", "post_id", Post},
{"Post", "post_id", posts, reflect.TypeOf([]Post{})},
}
// User is xorm struct
type User struct {
Id int64
Name string
}
// Post is xorm struct
type Post struct {
Post_id int64
Name string
Other string
}
我希望能够为 table 动态选择结构。
for _, rec := range ListOfTables {
//var entries []rec.XormStruct // this does not work, of course
//var entries []reflect.TypeOf(rec.XormStruct) // this does not work either
// xorm is *xorm.Engine
xorm.Find(&entries)
//xorm.Find(&rec.XormStruct2) //with interface{}, does not work - produces an empty &[]
posts3 := reflect.New(rec.XormStruct3).Interface()
//xorm.Find(&posts3) // same as above, produces empty &[]
var posts []Post
xorm.Find(&posts) // produces desired data
// afterwards I will do same to any table entries, e.g.
xml.Marshal(entries)
// so there is really no need to create identical functions for each table
}
目标 DRY(我有大约 30 tables,功能相同)
我试过:
要用
reflect.TypeOf()
,但是我看不懂if/how我可以用它(reflect.Type
)定义一个新的变量用
XormStruct interface{}
定义记录并为每个 ListOfTables 条目创建一个切片,例如var posts []Post
和{"Post", "post_id", posts},
正在搜索 SO 和 godocs
在我看来,xorm.Find()
并不是 "happy" 获得 interface{}
而不是 []Posts
,即使它没有这么说。
更新: 我相信最大的区别是:
spew.Dump(posts3) //posts3 := reflect.New(rec.XormStruct3).Interface()
// (*[]main.Post)<0x2312312>(<nil>)
spew.Dump(posts) //var posts []Post
// ([]main.Post)<nil>
解决方案
posts3 := reflect.New(rec.XormStruct3).Interface()
xorm.Find(posts3) // not &posts3
可以使用reflect.Type
to represent / describe a Go type. And at runtime, you may use reflect.New()
to obtain a pointer to the zeroed value of this type wrapped in a reflect.Value
. And if you need a slice instead of a single value, you may use reflect.SliceOf()
,或者先获取切片值的类型描述符
如果您存储表的 refect.Type
个值,您可以这样使用它:
type Record struct {
TableName string
PrimaryKey string
XormStruct reflect.Type
}
var ListOfTables [...]Record {
{"User", "id", reflect.TypeOf((*User)(nil)).Elem()},
{"Post", "post_id", reflect.TypeOf((*Post)(nil)).Elem()},
}
// User is xorm struct
type User struct {
Id int64
Name string
}
// Post is xorm struct
type Post struct {
Post_id int64
Name string
Other string
}
注意你必须使用导出字段!
然后处理表格:
for _, rec := range ListOfTables {
entries := reflect.New(reflect.SliceOf(t.XormStruct)).Interface()
err := xorm.Find(entries)
// Handle error
err := xml.Marshal(entries)
// Handle error
}
您可以使用 JSON 查看此的工作示例(概念证明)(没有 xorm
,因为它在 Go Playground 上不可用):Go Playground.
如果您首先要存储切片的 reflect.Type
个值:
var ListOfTables [...]Record {
{"User", "id", reflect.TypeOf([]User{})},
{"Post", "post_id", reflect.TypeOf([]Post{})},
}
而且使用起来也更简单:
for _, rec := range ListOfTables {
entries := reflect.New(t.XormStruct).Interface()
err := xorm.Find(entries)
// Handle error
err := xml.Marshal(entries)
// Handle error
}
查看此概念的证明:Go Playground。
请注意,如果 Record
包含切片类型(在字段 XormStruct
中),如果您需要访问结构的类型(结构的元素类型),您可以使用Type.Elem()
为此。