使用 []struct 与 Json

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

Using []struct with Json

问题

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

类型GITHUB_EVENT不支持索引

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

func httpGetEvents() {
    eventDataRAW := httpPageGet("https://api.github.com/events", true)
    eventDataJSON := new(GITHUB_EVENT)

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

    fmt.Println(eventDataJSON[0].Id)
}
type GITHUB_EVENT []struct {
    Id    string `json:"id"`
    Type  string `json:"type"`
    Actor struct {
        Id         int    `json:"id"`
        Login      string `json:"login"`
        GravatarId string `json:"gravatar_id"`
        Url        string `json:"url"`
        AvatarUrl  string `json:"avatar_url"`
    } `json:"actor"`
    Repo struct {
        Id   int    `json:"id"`
        Name string `json:"name"`
        Url  string `json:"url"`
    } `json:"repo"`
    Payload struct {
        PushId       int    `json:"push_id"`
        Size         int    `json:"size"`
        DistinctSize int    `json:"distinct_size"`
        Ref          string `json:"ref"`
        Head         string `json:"head"`
        Before       string `json:"before"`
        Commits      []struct {
            Sha    string `json:"sha"`
            Author struct {
                Email string `json:"email"`
                Name  string `json:"name"`
            } `json:"author"`
            Message  string `json:"message"`
            Distinct bool   `json:"distinct"`
            Url      string `json:"url"`
        } `json:"commits"`
    } `json:"payload"`
    Public    bool   `json:"public"`
    CreatedAt string `json:"created_at"`
}
英文:

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:

type GITHUB_EVENT does not support indexing

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

func httpGetEvents() {
	eventDataRAW := httpPageGet("https://api.github.com/events", true)
	eventDataJSON := new(GITHUB_EVENT)

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

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

//--------------------------------------------------------------------------------------//

type GITHUB_EVENT []struct {
	Id    string `json:"id"`
	Type  string `json:"type"`
	Actor struct {
		Id         int    `json:"id"`
		Login      string `json:"login"`
		GravatarId string `json:"gravatar_id"`
		Url        string `json:"url"`
		AvatarUrl  string `json:"avatar_url"`
	} `json:"actor"`
	Repo struct {
		Id   int    `json:"id"`
		Name string `json:"name"`
		Url  string `json:"url"`
	} `json:"repo"`
	Payload struct {
		PushId       int    `json:"push_id"`
		Size         int    `json:"size"`
		DistinctSize int    `json:"distinct_size"`
		Ref          string `json:"ref"`
		Head         string `json:"head"`
		Before       string `json:"before"`
		Commits      []struct {
			Sha    string `json:"sha"`
			Author struct {
				Email string `json:"email"`
				Name  string `json:"name"`
			} `json:"author"`
			Message  string `json:"message"`
			Distinct bool   `json:"distinct"`
			Url      string `json:"url"`
		} `json:"commits"`
	} `json:"payload"`
	Public    bool   `json:"public"`
	CreatedAt string `json:"created_at"`
}

答案1

得分: 1

这个语句:

eventDataJSON := new(GITHUB_EVENT)

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

(*eventDataJSON)[0].Id

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

eventDataJSON := make(GITHUB_EVENT, 0)

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

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

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

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

fmt.Println(eventDataJSON[0].Id)

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

var eventDataJSON GITHUB_EVENT

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

英文:

This statement:

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:

(*eventDataJSON)[0].Id

However, the more conventional approach is to use make:

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:

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

...and then index the slice directly:

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:

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:

确定