使用 []struct 与 Json

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

Using []struct with Json

问题

我正在尝试将JSON解析为[]struct,该JSON是从https://api.github.com/events获取的。然而,当我尝试访问数组中的每个struct时,出现错误:

  1. 类型GITHUB_EVENT不支持索引

我如何能够访问数组中的每个struct?

  1. func httpGetEvents() {
  2. eventDataRAW := httpPageGet("https://api.github.com/events", true)
  3. eventDataJSON := new(GITHUB_EVENT)
  4. _ = json.Unmarshal([]byte(eventDataRAW), &eventDataJSON)
  5. fmt.Println(eventDataJSON[0].Id)
  6. }
  1. type GITHUB_EVENT []struct {
  2. Id string `json:"id"`
  3. Type string `json:"type"`
  4. Actor struct {
  5. Id int `json:"id"`
  6. Login string `json:"login"`
  7. GravatarId string `json:"gravatar_id"`
  8. Url string `json:"url"`
  9. AvatarUrl string `json:"avatar_url"`
  10. } `json:"actor"`
  11. Repo struct {
  12. Id int `json:"id"`
  13. Name string `json:"name"`
  14. Url string `json:"url"`
  15. } `json:"repo"`
  16. Payload struct {
  17. PushId int `json:"push_id"`
  18. Size int `json:"size"`
  19. DistinctSize int `json:"distinct_size"`
  20. Ref string `json:"ref"`
  21. Head string `json:"head"`
  22. Before string `json:"before"`
  23. Commits []struct {
  24. Sha string `json:"sha"`
  25. Author struct {
  26. Email string `json:"email"`
  27. Name string `json:"name"`
  28. } `json:"author"`
  29. Message string `json:"message"`
  30. Distinct bool `json:"distinct"`
  31. Url string `json:"url"`
  32. } `json:"commits"`
  33. } `json:"payload"`
  34. Public bool `json:"public"`
  35. CreatedAt string `json:"created_at"`
  36. }
英文:

I'm trying to parse JSON to a []struct, the JSON is retrieved from https://api.github.com/events
However when I try to access each struct within the array I get an error:

  1. type GITHUB_EVENT does not support indexing

How am I able to access each struct within the array?

  1. func httpGetEvents() {
  2. eventDataRAW := httpPageGet("https://api.github.com/events", true)
  3. eventDataJSON := new(GITHUB_EVENT)
  4. _ = json.Unmarshal([]byte(eventDataRAW), &eventDataJSON)
  5. fmt.Println(eventDataJSON[0].Id)
  6. }
  7. //--------------------------------------------------------------------------------------//
  8. type GITHUB_EVENT []struct {
  9. Id string `json:"id"`
  10. Type string `json:"type"`
  11. Actor struct {
  12. Id int `json:"id"`
  13. Login string `json:"login"`
  14. GravatarId string `json:"gravatar_id"`
  15. Url string `json:"url"`
  16. AvatarUrl string `json:"avatar_url"`
  17. } `json:"actor"`
  18. Repo struct {
  19. Id int `json:"id"`
  20. Name string `json:"name"`
  21. Url string `json:"url"`
  22. } `json:"repo"`
  23. Payload struct {
  24. PushId int `json:"push_id"`
  25. Size int `json:"size"`
  26. DistinctSize int `json:"distinct_size"`
  27. Ref string `json:"ref"`
  28. Head string `json:"head"`
  29. Before string `json:"before"`
  30. Commits []struct {
  31. Sha string `json:"sha"`
  32. Author struct {
  33. Email string `json:"email"`
  34. Name string `json:"name"`
  35. } `json:"author"`
  36. Message string `json:"message"`
  37. Distinct bool `json:"distinct"`
  38. Url string `json:"url"`
  39. } `json:"commits"`
  40. } `json:"payload"`
  41. Public bool `json:"public"`
  42. CreatedAt string `json:"created_at"`
  43. }

答案1

得分: 1

这个语句:

  1. eventDataJSON := new(GITHUB_EVENT)

声明了eventDataJSON*GITHUB_EVENT(一个指向切片的指针),并将其初始化为nil指针。在解组后,你可以通过在索引之前显式解引用指针来访问第一个事件:

  1. (*eventDataJSON)[0].Id

然而,更常规的方法是使用make

  1. eventDataJSON := make(GITHUB_EVENT, 0)

它将eventDataJSON声明为GITHUB_EVENT,并将其初始化为空切片。(记住,make用于特殊的内置类型,如切片、映射和通道)。

你可以将这个切片的指针传递给json.Unmarshal

  1. _ = json.Unmarshal([]byte(eventDataRAW), &eventDataJSON)

然后直接对切片进行索引:

  1. fmt.Println(eventDataJSON[0].Id)

此外,json.Marshal会负责分配输出值,所以你可以声明eventDataJSON并跳过任何显式初始化:

  1. var eventDataJSON GITHUB_EVENT

示例:http://play.golang.org/p/zaELDgnpB2

英文:

This statement:

  1. eventDataJSON := new(GITHUB_EVENT)

declares eventDataJSON as *GITHUB_EVENT (a pointer to a slice), and initializes it as a nil pointer. After unmarshaling, you could access the first event by explicitly deref-ing the pointer before indexing:

  1. (*eventDataJSON)[0].Id

However, the more conventional approach is to use make:

  1. eventDataJSON := make(GITHUB_EVENT, 0)

which declares eventDataJSON as a GITHUB_EVENT, and initializes it as an empty slice. (Remember that make is for special built-in types such as slices, maps, and channels).

You could pass a pointer to this slice to json.Unmarshal:

  1. _ = json.Unmarshal([]byte(eventDataRAW), &eventDataJSON)

...and then index the slice directly:

  1. fmt.Println(eventDataJSON[0].Id)

Additionally, json.Marshal will take care of allocating the output value, so you could declare eventDataJSON and skip any explicit initialization:

  1. var eventDataJSON GITHUB_EVENT

Example: http://play.golang.org/p/zaELDgnpB2

huangapple
  • 本文由 发表于 2015年1月9日 01:09:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/27845726.html
匿名

发表评论

匿名网友

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

确定