2 回答
TA贡献1780条经验 获得超5个赞
由于您指出的原因,您不能在文档中使用接口。解码器没有关于要创建的类型的信息。
处理这个问题的一种方法是定义一个结构来保存类型信息:
type NodeWithType struct {
Node Node `bson:"-"`
Type string
}
type Workflow struct {
CreatedAt time.Time
StartedAt time.Time
CreatedBy string
Nodes []NodeWithType
}
在此类型上实现 SetBSON 功能。此函数应解码类型字符串,根据该字符串创建正确类型的值并解组为该值。
func (nt *NodeWithType) SetBSON(r bson.Raw) error {
}
TA贡献1788条经验 获得超4个赞
继西蒙福克斯关于实施的答案之后SetBSON,这里有一个更准确的答案。
让我们看一下原始代码:
type Workflow struct {
CreatedAt time.Time
StartedAt time.Time
CreatedBy string
Nodes []Node
}
type Node interface {
Exec() (int, error)
}
type EmailNode struct {
From string
To string
Subject string
Body string
}
type TwitterNode struct {
Tweet string
Image []byte
}
func (n *EmailNode) Exec() (int, error){
//send email
return 0, nil
}
func (n *TwitterNode) Exec() (int, error) {
//send tweet
return 0, nil
}
您现在要做的是:一旦您从 Mongo 解组 BSON 对象,您希望能够知道每个节点是 anEmailNode还是 a TwitterNode。
当您将节点存储为Node接口时,mgo 无法知道要实现什么结构,因此您必须明确告诉它。来了SetBSON。
在您的示例中,问题来自 this Workflow.Nodes,它是Node接口的一部分。由于它是一个简单的切片,因此最好创建一个自定义类型,mgo 在解组 BSON 时将能够调用该类型:
type NodesList []Node
// The updated Workflow struct:
type Workflow struct {
CreatedAt time.Time
StartedAt time.Time
CreatedBy string
Nodes NodesList
}
现在,您可以SetBSON对此进行实施NodesList并描述其工作原理。请注意,当您使用指针时,您可以定义变量中包含的内容:
// Note that you must use a pointer to the slice
func (list *NodesList) SetBSON(raw raw.BSON) error {
// Now you need to create the objects according to your
// own domain logic and what's contained inside "raw":
if raw.something {
*list = append(*list, &TwitterNode{})
} else {
*list = append(*list, &EmailNode{})
}
return nil
}
- 2 回答
- 0 关注
- 247 浏览
添加回答
举报