在Go中,如何将bson byte []数据解组成一个结构数组?

时间:2017-11-16 03:49:51

标签: database go struct bson

当结构数组传递到Unmarshal参数时,interface{} bson byte [] 数据到结构数组的最佳方法是什么?

出于演示目的,在以下代码中,我使用bson.Marshal()上的inStructArr来获取byte[]类型的数据。这样我就可以使用bson.Unmarshal(...)来管道outStructArr

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

type User struct {
    Name string
}

func DecodeArrData(inStructArr, outStructArr interface{}) {
    inStructArrData, _ := bson.Marshal(inStructArr)
    bson.Unmarshal(inStructArrData, outStructArr) // <-- Error happens here
    // What's the right way of accomplishing this?
}

func Main() {
    outUsers := &[]User{}
    inUsers := []User{User{"A"}, User{"B"}}

    DecodeArrData(inUsers, outUsers)
}

当我这样做时,我收到的错误消息是:Unsupported document type for unmarshalling: []User。这样做的正确方法是什么?

提前致谢!

1 个答案:

答案 0 :(得分:2)

MarshalUnmarshal函数适用于BSON文档,而不适用于BSON数组。

将切片包装在结构中以提供包所需的文档:

func DecodeArrData(inStructArr, outStructArr interface{}) error {
    in := struct{ Data interface{} }{Data: inStructArr}
    inStructArrData, err := bson.Marshal(in)
    if err != nil {
        return err
    }
    var out struct{ Data bson.Raw }
    if err := bson.Unmarshal(inStructArrData, &out); err != nil {
        return err
    }
    return out.Data.Unmarshal(outStructArr)
}

如果您愿意利用Marshal函数的未记录功能并在应用程序中添加一些BSON格式知识,那么您可以省略包装器。

Marshal的未记录特征是它将切片编码为BSON数组。 BSON数组可以使用bson.Raw值进行解码,其中Kind设置为数组的BSON代码(值为4),数据设置为数组数据:

func DecodeArrData(inStructArr, outStructArr interface{}) error {
    inStructArrData, err := bson.Marshal(inStructArr)
    if err != nil {
        return err
    }
    raw := bson.Raw{Kind: 4, Data: inStructArrData}
    return raw.Unmarshal(outStructArr)
}