登录
首页 >  Golang >  Go问答

将编码转换为内嵌结构的方法

来源:stackoverflow

时间:2024-03-02 13:30:27 426浏览 收藏

一分耕耘,一分收获!既然打开了这篇文章《将编码转换为内嵌结构的方法》,就坚持看下去吧!文中内容包含等等知识点...希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友们多留言评论,多给建议!谢谢!

问题内容

我希望能够在响应主体上使用 .decode() 来填充结构,而不必首先尝试找出应该解码为哪种类型的结构。

我有一个通用结构 match 来保存有关所玩游戏的信息,例如《堡垒之夜》中的一场比赛。在此结构中,我使用 matchdata 来保存整个游戏的比赛数据。

当解码到 matchdata 结构时,我发现底层嵌入类型已初始化,但具有所有默认值,而不是来自响应的值。

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,我更希望该函数可以不知道它。

我不确定这是否可能,但提前致谢。


解决方案


问题中的方法不起作用,因为嵌入的结构共享字段名称。尝试这种方法。

声明一个将游戏类型标识符与相关围棋类型关联起来的映射。这只是与解码相关的代码,它了解数百种游戏类型。

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

终于介绍完啦!小伙伴们,这篇关于《将编码转换为内嵌结构的方法》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布Golang相关知识,快来关注吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>