json - 如何解码为嵌入式结构?

标签 json go struct decode

我希望能够在响应主体上使用.Decode()来填充结构,而无需首先尝试弄清楚应该解码为哪种类型的结构。
我有一个通用结构Match来保存有关玩过的游戏的信息,例如Fortnite的一场比赛。在此结构中,我使用MatchData来保存游戏的整个比赛数据。
当解码为MatchData结构时,我发现底层嵌入类型已初始化,但是具有所有默认值,而不是来自respose的值。

type Match struct {
    MatchID       int        `json:"match_id"`
    GameType      int        `json:"game_type"`
    MatchData     *MatchData `json:"match_data"`
}

type MatchData struct {
    MatchGame1
    MatchGame2
}

type MatchGame1 struct {
    X int `json:"x"`
    Y int `json:"y"`
}

type MatchGame2 struct {
    X int `json:"x"`
    Y int `json:"y"`
}

func populateData(m *Match) (Match, error) {
    response, err := http.Get("game1.com/path")
    if err != nil {
        return nil, err
    }
    
    // Here, m.MatchData is set with X and Y equal to 0
    // when response contains values > 0
    err = json.NewDecoder(response.Body).Decode(&m.MatchData)
    if err != nil {
        return nil, err
    }

    return m, nil
}

编辑
预期的JSON有效负载示例。
{
    "x": 10,
    "y": 20
}
我可以通过检查m.GameType,创建一个对应的结构,然后将其分配给m.MatchData来解决该问题,但是如果我想添加另外100个游戏API,则我希望该功能与它无关。
我不确定这是否可能,但请先谢谢。

最佳答案

该问题中的方法将不起作用,因为嵌入式结构共享字段名称。试试这种方法。
声明将游戏类型标识符与关联的围棋类型相关联的 map 。这只是与解码相关的代码,它知道数百种游戏类型。

var gameTypes = map[int]reflect.Type{
    1: reflect.TypeOf(&MatchGame1{}),
    2: reflect.TypeOf(&MatchGame2{}),
}
将匹配数据解码为raw message。使用游戏类型创建比赛数据值并将其解码为该值。
func decodeMatch(r io.Reader) (*Match, error) {

    // Start with match data set to a raw messae.
    var raw json.RawMessage
    m := &Match{MatchData: &raw}

    err := json.NewDecoder(r).Decode(m)
    if err != nil {
        return nil, err
    }

    m.MatchData = nil

    // We are done if there's no raw message.
    if len(raw) == 0 {
        return m, nil
    }

    // Create the required match data value.
    t := gameTypes[m.GameType]
    if t == nil {
        return nil, errors.New("unknown game type")
    }
    m.MatchData = reflect.New(t.Elem()).Interface()

    // Decode the raw message to the match data.
    return m, json.Unmarshal(raw, m.MatchData)

}
Run it on the playground

关于json - 如何解码为嵌入式结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62662399/

相关文章:

javascript - 如何使用 Angular JS 访问 JSON 中的嵌套对象

android - 如何使用 Kotlin 从 android 中的 Assets 中读取 json 文件?

javascript - 删除json中的根节点

javascript - 使用 Angular 2 的 http.get() 从本地文件加载 json

Go:如何生成 bash shell

c - 指针数组 c

c++ - 从二进制文件 (C++) 读取结构的烦人错误

testing - 当测试文件在模块中时,如何运行 `go test`?

没有类型的Golang函数参数?

c - 将数组传递给 C 中的结构