首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >go json解组选项

go json解组选项
EN

Stack Overflow用户
提问于 2015-11-06 14:37:18
回答 1查看 1.6K关注 0票数 0

试图找到一个简单的解决方案,将封送/解压缩到以下结构中

代码语言:javascript
运行
复制
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)

如果:

代码语言:javascript
运行
复制
body = `{"data":[{"id":"1","type":"blah"}]}`

然而,我也需要它对以下问题作出回应:

代码语言:javascript
运行
复制
body = `{"data":{"id":"1","type":"blah"}}` //notice no slice

我可以做一个单独的类型

代码语言:javascript
运行
复制
type ResourceSingle struct {
    Data ResourceData `json:"data"`
}

但是,这意味着需要复制我附加到资源的所有功能,这是可能的。但是,在执行它之前,我需要找出要解封送回的类型,另外,当涉及到关系部分时,每个类型都可能包含数据:[]{}或数据{},这样这个想法就行不通了。

或者我可以用

代码语言:javascript
运行
复制
map[string]*json.RawMessage
//or
type Resource struct {
    Data *json.RawMessage `json:"data"`
}

但是,在json表单中,我如何知道它是一个片还是一个节点来提供要解编组的正确结构呢?

我的最后一招是将umarshal放入映射接口,并使用大量的反射测试。但这是一个很长的喘息期。

想法?

好样的,jJ

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-06 15:30:33

有很多方法来构造它,但是最简单的技术就是实现json.Unmarshaler,并检查数据的类型。您可以最小限度地解析json字节,通常只是第一个字符,或者您可以尝试将其解封为每个类型并返回成功的类型。

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

代码语言:javascript
运行
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33569210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档