我如何使用bson.SetBSON或bson.Raw?

问题描述 投票:0回答:1

可能相关:How to use interface type as a model in mgo (Go)?

我有这样的结构:

type Game struct {
    ID       bson.ObjectId
    Type     string
    Location string
    Details  interface{}
}

type FeudDetails struct {
    ...
}

type TriviaDetails struct {
    ...
}

type BingoDetails struct {
    ...
}

我想使用TypeGame字段将Details序列化为特定类型(例如FeudDetailsBingoDetails的实例)。它仍然是interface{}中的Game,但是我可以这样做:

feudDetails, ok := game.Details.(FeudDetails)
if ok {
    // we know this is a Feud game, and we have the details
    feudDetails.Round++
}

[The docs说使用bson.Raw可以“部分地将值编组或封送值”,但是它们没有提供我已经找到的任何示例。

我尝试使用:

func (game *Game) SetBSON(r bson.Raw) error {
    err := r.Unserialize(game)
    if err != nil {
        return nil
    }
    games[game.Type].LoadDetails(game)  // this calls a function based on the Type to
                                        // create a concrete value for that game.
    return nil
}

我在这里得到一个((ahem))堆栈溢出。我认为这是因为r.Unserialize递归调用SetBSON

我的目标是在所有字段上使用标准的反序列化except Details,然后能够使用game.Type确定如何处理Details。如果我做这样的事情:

type GameDetails interface{}

type Game struct {
    ...
    Details GameDetails
}

func (details *GameDetails) SetBSON(r bson.Raw) error {
    // game isn't defined
    games[game.Type].LoadDetails(r, details)
}

然后我如何访问外部的Type字段来知道将其反序列化为哪种游戏类型?

我还将接受“您做错了所有事情,Go中更好的模式是XYZ ...”]

EDIT:我也尝试了正常的反序列化,然后使用interface{}转换了Detailsgame.Details.(FeudDetails)版本,但是转换失败。我想我不能那样做,因为反序列化后的基础类型是[[not一个FeudDetails,但很可能是map[string]interface{}

EDIT 2:我以为会很聪明,并且在从数据库中检索对象时(使用C0调用game := Game{Details: FeudDetails: {}}之前,用正确的类型预填充了一个对象,但是我的trick俩没有用:] >db...One(&game)

可能相关:如何在mgo(Go)中将接口类型用作模型?我有一个这样的结构:type Game struct {ID bson.ObjectId Type string Location string Details ...
go bson mgo
1个回答
0
投票
在(取消)编组期间忽略DEBU[Mar 31 22:19:09.442] Caching show gid=5e814448ef5b9858b7ff4e57 TRAC[Mar 31 22:19:09.442] Before database call dtype=main.FeudDetails TRAC[Mar 31 22:19:09.446] After database call dtype=bson.M
© www.soinside.com 2019 - 2024. All rights reserved.