【问题标题】:What is the best way to handle "a single element or an array" JSON property in Go?在 Go 中处理“单个元素或数组”JSON 属性的最佳方法是什么?
【发布时间】:2016-06-30 17:33:40
【问题描述】:

现在我们有一个 JSON HTTP 请求数据,它是一个像 {"data": {"id":1}} 或像 {"data": [{"id":1}, {"id":2}]} 这样的元素数组。

由于客户端无法更改实现,因此我们必须保留并接受此数据结构。

目前我实现的结构如下:

type Request struct {
  rawData json.RawMessage `json:"data"`

  Data *Data `json:"-"`
  DataList []*Data `json:"-"`
}

首先将“data”属性作为json.RawMessage解析成变量req,先尝试解析为单个元素,如果失败则尝试解析为数组。

if err := json.Unmarshal(req.rawData, &req.Data); err != nil {
    if err := json.Unmarshal(req.RawData, &req.DataList); err != nil {
        return errors.New("could not parse data")
    } else if len(req.DataList) < 1 {
        return errors.New("empty list")
    }
}

在这种情况下,稍后当我们要使用这些数据时,我们可以通过len(req.Datalist) &gt;= 1 来检查rawData 是单个元素还是数组。 (或者我可以在解析时设置一些标志来显示结构中的isDataMultiple)。

除了我正在做的事情之外,还有什么惯用的方法可以在 Go 中实现相同的结果吗?

【问题讨论】:

  • 我个人只会将值设为数组。你可以有一个长度为 1 的数组。
  • 您的示例尝试解组单例,然后在失败时尝试将其作为数组执行,这是 Go 中处理此问题的最惯用方式。
  • onetwothreefour 的可能重复项。
  • >squiguy 我明白了,我喜欢这个主意:) >evanmcdonnal, >icza 是的,我知道有一些相关的问题,我想知道是否有一些标准化的解决方案。谢谢!

标签: json api go


【解决方案1】:

我会这样做:

type Request struct {
   RawData json.RawMessage `json:"data"`  // export field for unmarshal of entire request
   DataList []*Data `json:"-"`           // always use slice
}

// Is it an array?
if bytes.HasPrefix(bytes.TrimSpace(req.RawData), []byte{'['})) {
   if err := json.Unmarshal(req.RawData, &req.DataList); err != nil {
       // handle error parsing array
   }
} else {
   var v Data
   if err := json.Unmarshal(req.RawData, &v); err != nil {
       // handle error parsing single value
   }
   req.DataList = []*Data{&v)
}

【讨论】:

  • 我明白了。我们可以检查实际的第一个字节字符[,而不是尝试编组为单个元素。感谢您的建议!我喜欢它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
相关资源
最近更新 更多