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

在Go中解码可变模式JSON

在Go中解码可变模式JSON

Go
肥皂起泡泡 2021-05-03 16:48:47
我想问有关Go的问题encoding/json,但我想它也适用于将JSON Blob映射到任何语言的对象的任何其他JSON库。这是一个例子。如果您想使用goo.gl URL Shortener API来缩短URL ,则可以返回一个成功的响应:{ "kind": "urlshortener#url", "id": "http://goo.gl/fbsS", "longUrl": "http://www.google.com/"}或错误响应:{ "error": {  "errors": [   {    "domain": "global",    "reason": "required",    "message": "Required",    "locationType": "parameter",    "location": "resource.longUrl"   }  ],  "code": 400,  "message": "Required" }}有没有一种惯用的方式来处理这个问题-可能会遵循两个完全不同的模式的响应?通常,我使用地图/列表处理JSON;我知道Go中有可能。我可以解组到a map[string]interface{},然后检查地图是否已"error"作为关键。但是,我想我必须再次将其解码为适当的struct。(我错了吗?)我正在做这样的事情。对于每种响应,我都有一种类型:type successResponse struct {    Kind string    Id string    LongUrl string}type errorResponse struct {    Error struct {        Errors []struct {            Domain string            Reason string            Message string            LocationType string            Location string        }        Code int        Message string    }}解码看起来像这样:s := new(successResponse)err := json.Unmarshal(blob, s)if err == nil {    // handle success} else {    e := new(errorResponse)    err = json.Unmarshal(blob, e)    if err == nil {        // handle error response    } else {        // handle actual error    }}但这看起来很难看。我应该如何处理?
查看完整描述

3 回答

?
守候你守候我

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

由于json响应中的字段彼此不同,因此您只需创建一个具有所有字段并集的结构即可。json解码器将忽略json字符串中不存在的字段,并且您可以测试这些字段的存在,以了解要返回的响应类型。


查看完整回答
反对 回复 2021-05-17
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

我对此也感到困惑,并以为我必须再次对其进行解码。不过你没有。您只需要将interface {}数据类型转换为适当的结构。

例如,如果JSON包已经把值转换成通用的interface{},可以强制转换成ErrorTypeerror := val.(ErrorType)

如果要根据值的类型进行解析,则可以foo.(type)switch语句中使用“做正确的事”。

我本周只学习Go,所以它不是最漂亮的代码,但是geodns JSON配置解析中有一些示例。


查看完整回答
反对 回复 2021-05-17
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

type Response struct {

    Kind    string

    Id      string

    LongUrl string

    Error   struct {

        Errors []struct {

            Domain       string

            Reason       string

            Message      string

            LocationType string

            Location     string

        }

        Code    int

        Message string

    }

}


s := Response{}

if err := json.Unmarshal(blob, &s); err == nil {

    if s.Error == nil {

        // success

    } else {

        // error

    }

} else {

    // something went wrong

}


查看完整回答
反对 回复 2021-05-17
  • 3 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

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