如何将来自HTTP Get请求的数据存储在结构体切片中

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

How to store data from a HTTP Get request in a slice of structs

问题

问题
我是Go的新手,我正在尝试从Gov.uk公共假期API中将json数据存储在一个结构体中,以便稍后在我的前端中使用。

如果我运行

var sb = string(body)
fmt.Println(sb)

我可以在终端中看到返回的数据。我知道响应体由字节组成,上述代码将其转换为字符串。

我想遍历响应体并将数据存储在名为holidays的结构体切片中,每个结构体将包含一个公共假期的数据。但是,奇怪的是,holidays变量返回一个空切片:[]

我猜我有两个问题:

  1. 将json数据转换为结构体切片以供以后使用的最佳方法是什么?
  2. 为什么holidays变量返回一个空切片?

谢谢!

以下是我的代码:
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type Response struct {
	Data []Data
}

type Data struct {
	Division    string
	Bankholiday Bankholiday
}

type Bankholiday struct {
	Title string
	Date  string
}

func main() {
	resp, err := http.Get("https://www.gov.uk/bank-holidays.json")
	if err != nil {
		log.Fatal(err)
	}

	if resp.Body != nil {
		defer resp.Body.Close()
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln(err)
	}

	var response Response
	json.Unmarshal(body, &response)
	var holidays = []Bankholiday{}

	for _, date := range response.Data {
		holidays = append(holidays, Bankholiday{
			Title: date.Bankholiday.Title,
			Date:  date.Bankholiday.Date,
		})
	}

	fmt.Println("holidays: ", holidays)

}
英文:

Problem
I'm new to Go and I'm trying to store json data in a struct from the Gov.uk public holidays API, so I can use this later on in my frontend.

If I run

var sb = string(body)
fmt.Println(sb)

I can see the data that's being returned in my terminal. I know that the response body is made up of bytes and the above converts it to a string.

I would like to iterate through the response body and store the data in a slice of structs called holidays, each struct will contain the data for a single public holiday. For some reason, the holidays variable returns an empty slice: [].

I guess my two questions are:

  1. What's the best way to transform json data into a slice of structs to be used later on?
  2. Why does the holidays variable return an empty slice?

Thanks!

Here's my code below:
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type Response struct {
	Data []Data
}

type Data struct {
	Division    string
	Bankholiday Bankholiday
}

type Bankholiday struct {
	Title string
	Date  string
}

func main() {
	resp, err := http.Get("https://www.gov.uk/bank-holidays.json")
	if err != nil {
		log.Fatal(err)
	}

	if resp.Body != nil {
		defer resp.Body.Close()
	}

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln(err)
	}

	var response Response
	json.Unmarshal(body, &response)
	var holidays = []Bankholiday{}

	for _, date := range response.Data {
		holidays = append(holidays, Bankholiday{
			Title: date.Bankholiday.Title,
			Date:  date.Bankholiday.Date,
		})
	}

	fmt.Println("holidays: ", holidays)

}

答案1

得分: 2

我已经调整了Response struct以正确处理数据的解组。以下是工作代码:

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
)

type Response map[string]Data

type Data struct {
	Division string `json:"division"`
	Events   []struct {
		Title   string `json:"title"`
		Date    string `json:"date"`
		Notes   string `json:"notes"`
		Bunting bool   `json:"bunting"`
	} `json:"events"`
}

func main() {
	resp, err := http.Get("https://www.gov.uk/bank-holidays.json")
	if err != nil {
		log.Fatal(err)
	}

	if resp.Body != nil {
		defer resp.Body.Close()
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln(err)
	}

	var response Response
	if err = json.Unmarshal(body, &response); err != nil {
		log.Fatalln(err)
	}

	for div, _ := range response {
		for _, event := range response[div].Events {
			fmt.Printf("Division=%s, Holiday=%s, Date=%s\n", div, event.Title, event.Date)
		}

	}

}

希望对你有帮助!

英文:

I had to adjust the Response struct to handle correct unmarshaling of data. Find below the working code:

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
)

type Response map[string]Data

type Data struct {
	Division string `json:"division"`
	Events   []struct {
		Title   string `json:"title"`
		Date    string `json:"date"`
		Notes   string `json:"notes"`
		Bunting bool   `json:"bunting"`
	} `json:"events"`
}

func main() {
	resp, err := http.Get("https://www.gov.uk/bank-holidays.json")
	if err != nil {
		log.Fatal(err)
	}

	if resp.Body != nil {
		defer resp.Body.Close()
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatalln(err)
	}

	var response Response
	if err = json.Unmarshal(body, &response); err != nil {
		log.Fatalln(err)
	}

	for div, _ := range response {
		for _, event := range response[div].Events {
			fmt.Printf("Division=%s, Holiday=%s, Date=%s\n", div, event.Title, event.Date)
		}

	}

}

答案2

得分: 0

因为你的 JSON 字段必须与你的结构体匹配。

type Response map[string]Data

type Data struct {
	Division string  `json:"division"`
	Events   []Event `json:"events"`
}

type Event struct {
	Title   string `json:"title"`
	Date    string `json:"date"`
	Notes   string `json:"notes"`
	Bunting bool   `json:"bunting"`
}

请注意,上述代码是 Go 语言的结构体定义,其中使用了 json 标签来指定字段在 JSON 中的名称。这样做是为了确保在将 JSON 数据解析到结构体时,字段能够正确地匹配。

英文:

Because your json fields must match your structs.

type Response map[string]Data

type Data struct {
	Division string  `json:"division"`
	Events   []Event `json:"events"`
}

type Event struct {
	Title   string `json:"title"`
	Date    string `json:"date"`
	Notes   string `json:"notes"`
	Bunting bool   `json:"bunting"`
}

</details>



huangapple
  • 本文由 发表于 2022年8月8日 04:36:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/73270873.html
匿名

发表评论

匿名网友

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

确定