我正在寻找一种存储信息的函数应该使用的结构的方法。每个结构对应于某些数据库表。
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
}
我希望能够为表动态选择结构。
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张桌子,功能相同)
我努力了:
使用reflect.TypeOf()
,但我不知道是否/如何使用它(reflect.Type
)定义新变量
定义带有XormStruct interface{}
每个ListOfTables条目的Record,并创建一个切片,例如var posts []Post
和{"Post", "post_id", posts},
搜索SO和godocs
在我看来,即使不是这样,xorm.Find()
也不愿意“得到” 。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
用来表示/描述Go类型。并且在运行时,您可以使用reflect.New()
来获取指向包装在中的该类型的零值的指针reflect.Value
。并且,如果您需要切片而不是单个值,则可以使用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
}
您可以xorm
使用JSON: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
}
请参阅此概念证明:前往Playground。
请注意,如果Record
保存切片类型(在字段中XormStruct
),则如果您需要访问结构的类型(结构的元素类型),则可以使用Type.Elem()
它。
我在谷歌上搜索过,找不到任何可以在O(1)时间内存储和读取双向数据的DS。例如书籍和作家。有了书的名字,就必须找到作者。有了作者的名字,就必须找到书。 在数据库中,这些关系(如联接表)是如何存储的? 提前谢谢。
主要内容:图存储结构基本常识,图存储结构的分类我们知道,数据之间的关系有 3 种,分别是 "一对一"、"一对多" 和 "多对多",前两种关系的数据可分别用 线性表和树结构存储,本节学习存储具有"多对多"逻辑关系数据的结构—— 图存储结构。 图 1 图存储结构示意图 图 1 所示为存储 V1、V2、V3、V4 的图结构,从图中可以清楚的看出数据之间具有的"多对多"关系。例如,V1 与 V4 和 V2 建立着联系,V4 与 V1 和 V3 建立着
主要内容:树的结点,子树和空树,结点的度和层次,有序树和无序树,森林,树的表示方法,总结之前介绍的所有的 数据结构都是 线性存储结构。本章所介绍的树结构是一种非线性存储结构,存储的是具有“一对多”关系的数据元素的集合。 (A)
每条链有独立的数据存储文件 每个智能合约都独立的数据存储空间 每个智能合约可以创建多个数据表
主要内容:图的顺序存储结构C语言实现使用图结构表示的数据元素之间虽然具有“多对多”的关系,但是同样可以采用顺序存储,也就是使用数组有效地存储图。 使用数组存储图时,需要使用两个数组,一个数组存放图中顶点本身的数据(一维数组),另外一个数组用于存储各顶点之间的关系(二维数组)。 存储图中各顶点本身数据,使用一维数组就足够了;存储顶点之间的关系时,要记录每个顶点和其它所有顶点之间的关系,所以需要使用二维数组。 不同类型的图,存储的方式略
主要内容:广义表的另一种存储结构由于 广义表中既可存储原子(不可再分的数据元素),也可以存储子表,因此很难使用 顺序存储结构表示,通常情况下广义表结构采用 链表实现。 使用顺序表实现广义表结构,不仅需要操作 n 维数组(例如 {1,{2,{3,4}}} 就需要使用三维数组存储),还会造成存储空间的浪费。 使用链表存储广义表,首先需要确定链表中节点的结构。由于广义表中可同时存储原子和子表两种形式的数据,因此链表节点的结构也有两种,