为了账号安全,请及时绑定邮箱和手机立即绑定

go json解组选项

go json解组选项

Go
慕虎7371278 2021-11-22 14:52:08
试图找到一个简单的解决方案来编组/解组到以下结构中type Resource struct {    Data []ResourceData `json:"data"`}type ResourceData struct {    Id string  `json:"id"`    Type string  `json:"type"`    Attributes map[string]interface{} `json:"attributes"`    Relationships map[string]Resource `json:"relationships"`}r := Resource{}json.Unmarshal(body, &r)如果:body = `{"data":[{"id":"1","type":"blah"}]}`但是我也需要它来回应:body = `{"data":{"id":"1","type":"blah"}}` //notice no slice我可以做一个单独的类型type ResourceSingle struct {    Data ResourceData `json:"data"`}但是,这意味着需要复制我附加到资源的所有功能,这是可能的。但是,我需要在执行之前找出要解组的类型,而且当涉及到关系部分时,每个类型都可能包含数据:[]{} 或数据{},所以这个想法不会工作。或者我可以使用map[string]*json.RawMessage//ortype Resource struct {    Data *json.RawMessage `json:"data"`}但是,当以 json 形式存在时,我怎么知道它是一个切片还是一个节点来提供正确的结构以进行解组?我的最后一招是将 umarshal 转换为 map[string] 接口并使用大量反射测试..但这很冗长。想法?
查看完整描述

1 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

有多种方法可以构建它,但最简单的技术归结为实现 ajson.Unmarshaler并检查数据的类型。您可以最低限度地解析 json 字节,通常只是第一个字符,或者您可以尝试解组为每种类型并返回成功的类型。


我们将在这里使用后一种技术,并将 ResourceData 插入到切片中,而不管传入数据的格式如何,因此我们始终可以以相同的方式对其进行操作:


type Resource struct {

    Data []ResourceData

}


func (r *Resource) UnmarshalJSON(b []byte) error {

    // this gives us a temporary location to unmarshal into

    m := struct {

        DataSlice struct {

            Data []ResourceData `json:"data"`

        }

        DataStruct struct {

            Data ResourceData `json:"data"`

        }

    }{}


    // try to unmarshal the data with a slice

    err := json.Unmarshal(b, &m.DataSlice)

    if err == nil {

        log.Println("got slice")

        r.Data = m.DataSlice.Data

        return nil

    } else if err, ok := err.(*json.UnmarshalTypeError); !ok {

        // something besides a type error occurred

        return err

    }


    // try to unmarshal the data with a struct

    err = json.Unmarshal(b, &m.DataStruct)

    if err != nil {

        return err

    }

    log.Println("got struct")


    r.Data = append(r.Data, m.DataStruct.Data)

    return nil

}

http://play.golang.org/p/YIPeYv4AfT


查看完整回答
反对 回复 2021-11-22
  • 1 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信