【发布时间】:2017-12-18 00:01:58
【问题描述】:
在我的节点项目中,我总是在带有猫鼬的文档上使用virtuals properties,并希望在我的 golang 项目中使用相同的机制。我找不到实现此类功能的最佳方法。
我有一些结构,从我的数据库中检索到,并希望根据我的服务器配置(如 IP 地址等)添加字段。我想避免每次获取此集合的文档时调用相同的函数。
【问题讨论】:
在我的节点项目中,我总是在带有猫鼬的文档上使用virtuals properties,并希望在我的 golang 项目中使用相同的机制。我找不到实现此类功能的最佳方法。
我有一些结构,从我的数据库中检索到,并希望根据我的服务器配置(如 IP 地址等)添加字段。我想避免每次获取此集合的文档时调用相同的函数。
【问题讨论】:
最简单的方法是简单地向结构中添加一个方法来计算您想要的值,然后在需要时调用该方法。
例如:
type Person struct {
FirstName string `bson:"firstName"`
LastName string `bson:"lastName"`
}
func (p *Person) Name() string {
return p.FirstName + " " + p.LastName
}
func main() {
p := &Person{FirstName: "Bob", LastName: "Archer"}
fmt.Println(p.Name())
}
这样做的好处是Name() 将始终返回“正确”的名称,即使您在检索文档后修改了名字或姓氏。
如果你想避免总是计算结果,你可以将它存储在一个字段中,例如:
type Person struct {
FirstName string `bson:"firstName"`
LastName string `bson:"lastName"`
name string
}
func (p *Person) Name() string {
if p.name == "" {
p.name = p.FirstName + " " + p.LastName
}
return p.name
}
请注意,当保存 Person 的值时,name 字段不会被持久化,因为它不会被导出。
如果您想自动执行此操作(例如,您希望在从 MongoDB 获取文档时自动计算 name),您可以通过实现 bson.Setter 接口来编写自定义解组逻辑。自定义解组逻辑没有什么特别之处,只是在执行默认编组逻辑后计算和设置name 字段。
例如:
type Person struct {
FirstName string `bson:"firstName"`
LastName string `bson:"lastName"`
name string
}
func (p *Person) SetBSON(raw bson.Raw) (err error) {
type my Person
if err = raw.Unmarshal((*my)(p)); err != nil {
return
}
p.name = p.FirstName + " " + p.LastName
return nil
}
如果您希望导出 name 字段,例如Name,那么你可以使用- bson标签值来排除这个字段保存到MongoDB,例如:
type Person struct {
FirstName string `bson:"firstName"`
LastName string `bson:"lastName"`
Name string `bson:"-"`
}
【讨论】: