创建一个用于这个 JSON 的结构体时遇到了问题。

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

Having issues creating a struct for this JSON

问题

我非常非常新手golang(使用这个项目来更好地学习这门语言)。我有一个API,我想从中获取数据,但是我似乎无法创建正确类型的结构体。

我尝试使用JSON to Go转换器转换JSON数据,但是返回的结构体太大了(Go返回错误)。我尝试手动创建一个带有切片的结构体,如下所示:

type osrsPrices []struct {
	ID struct {
		High     int `json:"high"`
		Hightime int `json:"highTime"`
		Low      int `json:"low"`
		Lowtime  int `json:"lowTime"`
	} `json:"id"`
}

每当我尝试从终端运行时,都会出现错误**"json: cannot unmarshal object into Go value of type main.osrsPrices exit status 1"**。

这是我使用的完整代码:

package main

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

type osrsPrices []struct {
	ID struct {
		High     int `json:"high"`
		Hightime int `json:"highTime"`
		Low      int `json:"low"`
		Lowtime  int `json:"lowTime"`
	} `json:"id"`
}

func main() {
	url := "https://prices.runescape.wiki/api/v1/osrs/latest"

	spaceClient := http.Client{
		Timeout: time.Second * 2, // Timeout after 2 seconds
	}

	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		log.Fatal(err)
	}

	req.Header.Set("User-Agent", "skillerscape:LearningGoLang|priceChecker")

	res, getErr := spaceClient.Do(req)
	if getErr != nil {
		log.Fatal(getErr)
	}

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

	body, readErr := ioutil.ReadAll(res.Body)
	if readErr != nil {
		log.Fatal(readErr)
	}

	items := osrsPrices{}
	jsonErr := json.Unmarshal(body, &items)
	if jsonErr != nil {
		log.Fatal(jsonErr)
	}

	for _, item := range items {
		fmt.Println(item)
	}
}

我相当确定错误与我处理数据的方式有关,但是尽管搜索了几个小时,我无法直接找到问题和解决方案。感谢任何人对这个问题的帮助。

英文:

I am very, very new to golang (using this project as a way to learn the language better). I have an api I'd like to pull data from, but I can't seem to create the right type of struct for it.

The full JSON I am trying to encode is located here. https://prices.runescape.wiki/api/v1/osrs/latest

The structure of the JSON is

{
"data": {
"2": {
"high": 182,
"highTime": 1621811749,
"low": 180,
"lowTime": 1621811755
},
"6": {
"high": 186683,
"highTime": 1621811083,
"low": 184528,
"lowTime": 1621811286
},
... REPEATS THOUSANDS OF TIMES ...
}
}

I have tried using the JSON to Go converter for the JSON data, but that returns a struct that is entirely too large. (Go returns an error) I have tried to manually make a struct with a slice as follows

type osrsPrices []struct {
ID struct {
High     int `json:"high"`
Hightime int `json:"highTime"`
Low      int `json:"low"`
Lowtime  int `json:"lowTime"`
} `json:"id"`
}

Whenever I try to run this from the terminal I am presented with the error "json: cannot unmarshal object into Go value of type main.osrsPrices exit status 1"

Here is the entire code I am using

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
type osrsPrices []struct {
ID struct {
High     int `json:"high"`
Hightime int `json:"highTime"`
Low      int `json:"low"`
Lowtime  int `json:"lowTime"`
} `json:"id"`
}
func main() {
url := "https://prices.runescape.wiki/api/v1/osrs/latest"
spaceClient := http.Client{
Timeout: time.Second * 2, // Timeout after 2 seconds
}
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("User-Agent", "skillerscape:LearningGoLang|priceChecker")
res, getErr := spaceClient.Do(req)
if getErr != nil {
log.Fatal(getErr)
}
if res.Body != nil {
defer res.Body.Close()
}
body, readErr := ioutil.ReadAll(res.Body)
if readErr != nil {
log.Fatal(readErr)
}
items := osrsPrices{}
jsonErr := json.Unmarshal(body, &items)
if jsonErr != nil {
log.Fatal(jsonErr)
}
for _, item := range items {
fmt.Println(item)
}
}

I am pretty sure the error has to do with the way I am trying to process the data, but I cannot figure out the issue directly, nor the solution despite a couple hours of googling. I appreciate any help anyone has on this issue.

答案1

得分: 1

在最深层次上,你有:

type Price struct {
   High     int `json:"high"`
   Hightime int `json:"highTime"`
   Low      int `json:"low"`
   Lowtime  int `json:"lowTime"`
}

这是一个具有可变键的对象,所以你需要:

type Data struct {
   Data map[string]Price `json:"data"`
}

然后你可以将其解组为该结构的实例:

var data Data
json.Unmarshal(input, &data)
英文:

At the deepest level, you have:

type Price struct {
High     int `json:"high"`
Hightime int `json:"highTime"`
Low      int `json:"low"`
Lowtime  int `json:"lowTime"`
}

This is in an object with variable keys, so you need:

type Data struct {
Data map[string]Price `json:"data"`
}

Then you can unmarshal into an instance of this struct:

var data Data
json.Unmarshal(input,&data)

huangapple
  • 本文由 发表于 2021年5月24日 07:32:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/67665235.html
匿名

发表评论

匿名网友

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

确定