我正在尝试使用Golang将API的响应映射到结构。
我在浏览器中查看链接时返回的JSON如下:
{
"GBP": 657.54
}
我只是想将它映射到一个简单的结构,如下所示:
type Price struct {
Name string
Value float64
}
这是我目前的代码。
func FetchCoinPrice(fsym string, tsyms string) Price {
url := fmt.Sprintf("https://min-api.cryptocompare.com/data/price?fsym=" + fsym + "&tsyms=" + tsyms)
fmt.Println("Requesting data from " + url)
price := Price{}
// getting the data using http
request, err := http.Get(url)
if err != nil {
log.Fatal(err.Error())
}
// Read the response body using ioutil
body, err := ioutil.ReadAll(request.Body)
if err != nil {
log.Fatal(err.Error())
}
defer request.Body.Close()
if request.StatusCode == http.StatusOK {
json.Unmarshal(body, &price)
}
return price
}
目前我收到的是一个空结构,我知道该链接正在恢复正确的数据,我已经在浏览器中对其进行了测试。
答案 0 :(得分:5)
映射不起作用。相反,您应该使用地图:
data := []byte(`{
"GBP": 657.54
}`)
priceMap := map[string]float64{}
err := json.Unmarshal(data, &priceMap)
// Check your errors!
if err != nil {
log.Fatal(err.Error())
}
fmt.Println(priceMap)
这将打印:
map[GBP:657.54]
然后,您可以迭代地图并构建上面提到的结构,或者只是在知道货币时直接访问该条目。例如:priceMap["GBP"]
您应该检查错误,特别是如果您没有从Unmarshal
获得预期的输出。
答案 1 :(得分:2)
问题在于,解组者无法猜测JSON对象中的 keys 应该对应于结构中的某些值。 Golang JSON映射根本不起作用。
但是,您可以将“价格”类型implement json.Unmarshaler
反序列化为浮点数(map[string]float64
),然后确保形状正确并相应地填充结构:
func (p *Price) UnmarshalJSON(bs []byte) error {
kvs := map[string]float64{}
err := json.Unmarshal(bs, &kvs)
if err != nil {
return err
}
if len(kvs) != 1 {
return fmt.Errorf("expected 1 key, got %d", len(kvs))
}
for name, value := range kvs {
p.Name, p.Value = name, value
}
return nil
}
func main() {
jsonstr := `[{"GBP":657.54},{"USD":123.45}]`
ps := []Price{}
err := json.Unmarshal([]byte(jsonstr), &ps)
if err != nil {
panic(err)
}
// ps=[]main.Price{
// main.Price{Name:"GBP", Value:657.54},
// main.Price{Name:"USD", Value:123.45}
// }
}