Go 动态JSON解码

Go 动态JSON解码,go,Go,我有这个函数来解析HTTP结果: func (a *Admin) ResponseDecode(structName string, body io.Reader) (interface{}, error) { content, err := ioutil.ReadAll(body) if err != nil { return nil, err } switch structName { case "[]Cat": var data []Cat err = json

我有这个函数来解析HTTP结果:

func (a *Admin) ResponseDecode(structName string, body io.Reader) (interface{}, error) {
content, err := ioutil.ReadAll(body)

if err != nil {
    return nil, err
}

switch structName {
case "[]Cat":
    var data []Cat
    err = json.Unmarshal(content, &data)

    if err != nil {
        return nil, err
    }
    return data, err

case "[]Dog":
    var data []Dog
    err = json.Unmarshal(content, &data)

    if err != nil {
        return nil, err
    }
    return data, err
default:
    log.Fatal("Can't decode " + structName)
}

return nil, nil
}
我在此方法之后执行类型断言:

parsed, err := a.ResponseDecode("[]Cat", resp.Body)

if err != nil {
    return nil, err
}

return parsed.([]Cat), nil
但如何避免代码重复:

var data []Stuff
err = json.Unmarshal(content, &data)

if err != nil {
    return nil, err
}
return data, err

每次我添加对象时?通常我会使用泛型,但这是去。这样做的好方法是什么?

您正在传入结构的名称,然后需要该类型的数据。相反,您只需传递结构:

var parsed []Cat
err := a.ResponseDecode(&parsed, resp.Body)
其中:

func (a *Admin) ResponseDecode(out interface{}, body io.Reader)  error {
  content, err := ioutil.ReadAll(body)
   if err != nil {
      return nil, err  
   }
  return json.Unmarshal(content,out)
}
事实上,您可以去掉ResponseCode函数:

var parsed []Cat
err:=json.NewDecoder(body).Decode(&parsed)

找到了我要找的东西。 此功能完成以下工作:

func (a *Admin) ResponseDecode(body io.Reader, value interface{}) (interface{}, error) {
content, err := ioutil.ReadAll(body)

if err != nil {
    return nil, err
}

err = json.Unmarshal(content, &value)

if err != nil {
    return nil, err
}

return value, nil}

应该注意的是,使用最后一种方法,可能会有人发送一个非常大的请求主体,使服务器崩溃。您可以通过使用设置一个正常的最大值来保护自己