如何将JSON数组解析为结构体(Struct)?

huangapple go评论124阅读模式
英文:

How to parse a JSON array into a Struct

问题

给定以下的REST调用...

  1. https://api.bitfinex.com/v2/ticker/fUSD

...我得到以下的JSON数组作为结果:

  1. [0.00073995,0.00067,30,10082128.5775703,0.000664,2,191337.1001453,-0.00003991,-0.057,0.00066009,94710166.80102274,0,0]

下面是我解析结果的方法:

  1. const (
  2. URL = "https://api.bitfinex.com/v2/ticker/f"
  3. )
  4. type Tick struct {
  5. FlashReturnRate float64
  6. Bid float64
  7. BidPeriod int64
  8. BidSize float64
  9. Ask float64
  10. AskPeriod int64
  11. AskSize float64
  12. DailyChange float64
  13. DailyChangePerc float64
  14. LastPrice float64
  15. Volume float64
  16. High float64
  17. Low float64
  18. }
  19. ...
  20. func (s *TickerService) Get(curry string) (*Tick, error) {
  21. req, err = http.NewRequest("GET", URL + curry, nil)
  22. if err != nil {
  23. return nil, err
  24. }
  25. resp, err := http.DefaultClient.Do(req); if err != nil {
  26. return nil, err
  27. }
  28. defer resp.Body.Close()
  29. var v []float64
  30. err = json.Unmarshal(resp.Body, &v)
  31. if err != nil {
  32. return nil, err
  33. }
  34. t := Tick{
  35. FlashReturnRate: v[0],
  36. Bid: v[1],
  37. BidSize: v[2],
  38. BidPeriod: int64(v[3]),
  39. Ask: v[4],
  40. AskSize: v[5],
  41. AskPeriod: int64(v[6]),
  42. DailyChange: v[7],
  43. DailyChangePerc: v[8],
  44. LastPrice: v[9],
  45. Volume: v[10],
  46. High: v[11],
  47. Low: v[12],
  48. }
  49. return &t, nil
  50. }

有没有更好的方法来构建Tick对象?

英文:

Given the following REST call...

  1. https://api.bitfinex.com/v2/ticker/fUSD

... I get back the following result as a JSON array:

  1. [0.00073995,0.00067,30,10082128.5775703,0.000664,2,191337.1001453,-0.00003991,-0.057,0.00066009,94710166.80102274,0,0]

Here below is how I parse the result:

  1. const (
  2. URL = "https://api.bitfinex.com/v2/ticker/f"
  3. )
  4. type Tick struct {
  5. FlashReturnRate float64
  6. Bid float64
  7. BidPeriod int64
  8. BidSize float64
  9. Ask float64
  10. AskPeriod int64
  11. AskSize float64
  12. DailyChange float64
  13. DailyChangePerc float64
  14. LastPrice float64
  15. Volume float64
  16. High float64
  17. Low float64
  18. }
  19. ...
  20. func (s *TickerService) Get(curry string) (*Tick, error) {
  21. req, err = http.NewRequest("GET", URL + curry, nil)
  22. if err != nil {
  23. return nil, err
  24. }
  25. resp, err := http.DefaultClient.Do(req); if err != nil {
  26. return nil, err
  27. }
  28. defer resp.Body.Close()
  29. var v []float64
  30. err = json.Unmarshal(resp.Body, &v)
  31. if err != nil {
  32. return nil, err
  33. }
  34. t := Tick{
  35. FlashReturnRate: v[0],
  36. Bid: v[1],
  37. BidSize: v[2],
  38. BidPeriod: int64(v[3]),
  39. Ask: v[4],
  40. AskSize: v[5],
  41. AskPeriod: int64(v[6]),
  42. DailyChange: v[7],
  43. DailyChangePerc: v[8],
  44. LastPrice: v[9],
  45. Volume: v[10],
  46. High: v[11],
  47. Low: v[12],
  48. }
  49. return &t, nil
  50. }

Is there a better way to build the Tick object?

答案1

得分: 1

你正在走在正确的道路上,但一个更可用的解决方案是创建一个自定义的解码器:

  1. func (t *Tick) UnmarshalJSON(data []byte) error {
  2. var v []float64
  3. if err := json.Unmarshal(data, &v); err != nil {
  4. return err
  5. }
  6. t.FlashReturnRate = v[0]
  7. t.Bid = v[1]
  8. t.BidSize = int64(v[2]) // 这是一个整数吗?你的示例数据表明是,但你的代码表明不是。
  9. // ... 等等
  10. return nil
  11. }

现在你可以直接将数据解码到你的 Tick 数据类型中:

  1. var tick Tick
  2. if err := json.Unmarshal(res.Body, &tick); err != nil {
  3. // 处理错误
  4. }
英文:

You're on the right track, but a more usable solution would be to create a custom unmarshaler:

  1. func (t *Tick) UnmarshalJSON(data []byte) error {
  2. var v []float64
  3. if err := json.Unmarshal(data, &v); err != nil {
  4. return err
  5. }
  6. t.FlashReturnRate = v[0]
  7. t.Bid = v[1]
  8. t.BidSize = int64(v[2]) // Is this an int? Your sample data suggests it is, your code suggests it isn't.
  9. // ... etc
  10. return nil
  11. }

Now you can unmarshal directly to your Tick data type as:

  1. var tick Tick
  2. if err := json.Unmarshal(res.Body, &tick); err != nil {
  3. // Handle error
  4. }

huangapple
  • 本文由 发表于 2017年9月13日 02:19:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/46183083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定