使用 mgo 在 MongoDB 模型中嵌入接口
当使用涉及不同类型节点的工作流系统时,通常使用 Go 接口来表示不同的节点类型。然而,当使用 mgo 将这些工作流存储在 MongoDB 中时,这种方法提出了挑战。
考虑以下示例:
<code class="go">type Workflow struct { CreatedAt time.Time StartedAt time.Time CreatedBy string Nodes []Node } type Node interface { Exec() (int, error) }</code>
其中 Node 是一个具有单一方法 Exec() 的接口,可以通过不同的节点类型来实现。
要将工作流存储在 MongoDB 中,您可以尝试通过 ID 查找它:
<code class="go">w = &Workflow{} collection.FindID(bson.ObjectIdHex(id)).One(w)</code>
但是,您会遇到错误,因为 mgo 无法解组将 Node 接口直接嵌入到 Go 结构中。这是因为它缺乏必要的类型信息来为每个节点创建适当的具体类型。
要解决此问题,您可以定义一个显式保存节点类型和实际节点值的结构体:
<code class="go">type NodeWithType struct { Node Node `bson:"-"` Type string } type Workflow struct { CreatedAt time.Time StartedAt time.Time CreatedBy string Nodes []NodeWithType }</code>
通过使用 bson:"-",Node 子字段被排除在自动解码之外,而是在 SetBSON 函数中手动处理:
<code class="go">func (nt *NodeWithType) SetBSON(r bson.Raw) error { // Decode the node type from the "Type" field // Create a new instance of the concrete node type based on the decoded type // Unmarshal the remaining document into the concrete node type //... }</code>
这种方法允许 mgo 识别 Node 的类型每个节点并在解码过程中创建适当的具体实例,解决类型信息问题。
以上是如何使用 mgo 在 MongoDB 模型中嵌入 Go 接口?的详细内容。更多信息请关注PHP中文网其他相关文章!