我试图通过使用嵌套结构来跨共享数据的对象最大化代码重用。请考虑以下代码:
package main
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
var collection *mgo.Collection
type Identifiable interface {
GetId() bson.ObjectId
}
type A struct {
Id bson.ObjectId `bson:"_id"`
A_value int
}
type B struct {
A `bson:",inline"`
B_value int
}
func (self *A) GetId() bson.ObjectId {
return self.Id
}
func setAValue(value int, a *A) {
a.A_value = value
commit(a)
}
func commit(i Identifiable) {
collection.UpsertId(i.GetId(), i)
}
func main() {
session, _ := mgo.Dial("localhost")
collection = session.DB("test").C("my_collection")
b := B{A: A{Id: bson.NewObjectId(), A_value: 1}, B_value: 2}
commit(&b)
}
此时,mongo中的记录看起来像这样(正如我所料):
{" _id" :ObjectId(" 54f0e231eefbfe049c000001")," a_value" :1," b_value" :2}
但是我想做这样的事情以避免编写冗余函数:
setAValue(42, &b.A)
问题是,这会导致数据丢失,因为它会替换整个条目,而不仅仅是更新它:
{" _id" :ObjectId(" 54f0df4eeefbfe0474000001")," a_value" :42}
有没有办法执行这样的更新,而不会消除任何不属于A
的值?或者我只是完全以错误的方式解决这个问题?
答案 0 :(得分:0)
问题是setAValue
提交类型A,而不是B.新提交的BSON值不包含B_value
。
我认为你应该将set function和commit函数分开。您可以通过反射或接口解决此设置和提交问题,但只是拆分功能更简单。