2

使用gopkg.in/mgo.v2/bson,我想知道如何将 interface{} 值编组为 type 的值bson.Raw

状态的文档bson.Raw

使用这种类型,可以部分地解组或编组值。

但我找不到会返回的 Marshal 函数bson.Raw

我错过了什么?

我尝试做的示例:

package main

import (
    "fmt"

    "gopkg.in/mgo.v2/bson"
)

func main() {
    // How to avoid a MarshalRaw help function?
    raw, err := MarshalRaw("Hello world")
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", raw)
}

func MarshalRaw(v interface{}) (*bson.Raw, error) {
    bin, err := bson.Marshal(struct{ Raw interface{} }{v})
    if err != nil {
        return nil, err
    }

    var raw struct{ Raw bson.Raw }
    err = bson.Unmarshal(bin, &raw)
    if err != nil {
        return nil, err
    }

    return &raw.Raw, nil
}

输出:

&{种类:2 数据:[12 0 0 0 72 101 108 108 111 32 119 111 114 108 100 0]}

4

2 回答 2

3

bson.Raw在编组和解组时都用作值。

要将 aninterface{}转换为 a bson.Raw,首先要做的是对其进行编组,以便获得代表正在编组的内容的纯文档数据:

    var value interface{} = bson.M{"some": "value"}
    data, err := bson.Marshal(value)
    if err != nil {
            log.Fatal(err)
    }

然后它可能有一个或多个字段解组为bson.Raw值:

    var doc struct{ Some bson.Raw }
    err = bson.Unmarshal(data, &doc)
    if err != nil {
            log.Fatal(err)
    }

甚至整个文档:

    var doc bson.Raw
    err = bson.Unmarshal(data, &doc)
    if err != nil {
            log.Fatal(err)
    }

如果您想要整个文档而不仅仅是一个字段,您还可以使用此快捷方式:

    doc := bson.Raw{3, data}

3 常量代表bson 规范中的一个文档,它当然必须与提供的数据匹配。由于 BSON 只支持顶层的文档,我们知道这一定是正确的。

于 2014-08-13T13:28:48.847 回答
2

我相信 bson.Raw 旨在用作变量的类型。

例如:(在比赛中

type Bar struct {
   AnInt int
   AString bson.Raw
}

“AString”字段将保留为您的链接提到的 bson.Raw 结构。

如果您想部分解码嵌套结构的顶层以找出它的实际类型,那么这将非常有用,以便您可以将其余部分解析为正确的数据类型。

注意,以上内容未经测试,不在我目前可以实际运行的机器前进行。这是基于它像标准 encoding/json 包一样工作的假设。

于 2014-08-13T02:29:22.167 回答