假设您的工作流由多个不同类型的嵌入式节点组成 . 由于节点的类型不同,我想在这里使用Golang接口并提出以下内容:
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
}
这些工作流程存储在MongoDB中,我有样本种子数据 . 使用mgo,当我尝试查找工作流程(给定其ID)时:
w = &Workflow{}
collection.FindID(bson.ObjectIdHex(id)).One(w)
我得到错误 - 类型bson.M的值不能分配给类型Node .
我觉得mgo如何在没有任何类型信息的情况下将嵌入式Node文档解组为Go结构,这也让我觉得有点奇怪 . 可能我需要从另一个角度来看问题 .
任何建议都将受到高度赞赏 .
2 回答
出于上述原因,您无法在文档中使用界面 . 解码器没有关于要创建的类型的信息 .
处理此问题的一种方法是定义一个结构来保存类型信息:
在此类型上实现SetBSON功能 . 此函数应解码类型字符串,根据该字符串创建正确类型的值并解组到该值 .
按照Simon Fox关于
SetBSON
实施的回答,这是一个更精确的答案 .我们来看一段原始代码:
你现在要做的是:一旦你从Mongo解组BSON对象,你希望能够知道每个节点是
EmailNode
还是TwitterNode
.当您将节点存储为
Node
接口时,mgo无法知道要实现的结构,因此您必须明确告知它 . 这是SetBSON
.在您的示例中,问题来自
Workflow.Nodes
,它是Node
接口的一部分 . 因为它是一个简单的切片,最好的是你创建一个自定义类型,当解组BSON时mgo将能够调用它:现在,您可以在
NodesList
上实现SetBSON
并描述它是如何工作的 . 请注意,当您使用指针时,您可以定义变量中包含的内容: