我正在尝试使用golang尝试将JSON文件解码为某些结构的一个相当简单的示例。但是,当我试图得到错误
时json:无法将对象解组为类型为[] main.Track
的Go值
我不明白。这是相关代码,JSON可以是found here。
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
// Tracks a group of Track types
type Tracks struct {
Tracks []Track
}
// Track represents a singular track
type Track struct {
Name string
URL string
Artist Artist
}
// Artist represents a single artist
type Artist struct {
Name string
MBID string
URL string
}
func main() {
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
response, err := http.Get(url)
if err != nil {
fmt.Printf("%s\n", err)
os.Exit(1)
}
defer response.Body.Close()
var tracks Tracks
decodeErr := json.NewDecoder(response.Body).Decode(&tracks)
if decodeErr != nil {
fmt.Printf("%s\n", decodeErr)
os.Exit(1)
}
for _, track := range tracks.Tracks {
fmt.Printf("%s: %s\n", track.Artist.Name, track.Name)
}
}
我最初的想法是,您可能需要使用结构对每个JSON值进行分类,这是我没有做过的,但是在阅读this article时会说:
这有两个答案。当您知道数据的外观时,简单的选项是将JSON解析为您定义的结构。 任何不适合结构的字段都将被忽略。我们将首先介绍该选项。
这让我相信它并非如此。
在这种情况下,我做错了什么?
答案 0 :(得分:1)
如果查看对查询的响应的JSON结构,您将看到返回具有tracks
属性的单个对象。
{
"tracks": {
"track": [ {...} ]
}
}
如果将此与给定结构进行比较,则可以看到结构未对齐。您给定的Tracks
结构具有一个Track
s片段的字段。如果我将其转换为JSON,则表示为以下内容。
{
"tracks": [ { ... } ]
}
这是您错误的根源。 JSON解码器期望根JSON对象的tracks
字段是一个数组。返回的是包含tracks
属性的对象,但其值是另一个JSON对象,其中包含 轨道数组的track
属性。您可以更新结构以反映此模式,如下所示。
// A response object from the API
type Response struct {
Tracks Tracks
}
// Tracks a group of Track types
type Tracks struct {
Track []Track
}
// Track represents a singular track
type Track struct {
Name string
URL string
Artist Artist
}
答案 1 :(得分:0)
Go类型的结构必须与JSON数据中的结构匹配。该应用程序缺少此JSON的粗体范围的嵌套级别:{“track”:{“track”: [{
以下是更新类型以匹配JSON的方法:
type Tracks struct {
Tracks struct {
Track []Track
}
}
...
for _, track := range tracks.Tracks.Track {
fmt.Printf("%s: %s\n", track.Artist.Name, track.Name)
}