json:无法将数组解组为main类型的Go值

问题描述:

I'm trying to read a json file with golang but i'm getting this error. I've checked almost every question about it but still couldnt get it.

Here's the example json file: https://jsonplaceholder.typicode.com/posts

And my code:

package main

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

type Posts struct {
    Post []struct{
        UserId int `json:"userId"`
        ID int `json:"id"`
        Title string `json:"title"`
        Body string `json:"body"`
    }
}

func main (){
    resp, err := http.Get("https://jsonplaceholder.typicode.com/posts")

    if err != nil {
        log.Fatal(err)
    }

    content, _ := ioutil.ReadAll(resp.Body)

    var posts Posts

    parsed := json.Unmarshal([]byte(content), &posts)

    //fmt.Println(string(content))

    fmt.Println(parsed)

}

Posts is an array of Post struct but you defined Post as array it is your first mistake, also Unmarshal doesn't returns result it returns only error and fills given parameter.

package main

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

type Post struct {
        UserId int `json:"userId"`
        ID int `json:"id"`
        Title string `json:"title"`
        Body string `json:"body"`
}

type Posts []Post


func main (){
    resp, err := http.Get("https://jsonplaceholder.typicode.com/posts")

    if err != nil {
        log.Fatal(err)
    }

    content, _ := ioutil.ReadAll(resp.Body)

    var posts Posts

    err = json.Unmarshal(content, &posts)

    if err != nil {
        log.Fatal(err)
    }


    fmt.Println(posts[0].Body)

}

That JSON is, at its root, an array. You're trying to unmarshal it into an object, which contains, as a field, an array - hence the error that you passed an object when the JSON is an array. You want to pass an array (or slice, really), as in:

type Post struct {
    UserId int `json:"userId"`
    ID int `json:"id"`
    Title string `json:"title"`
    Body string `json:"body"`
}

//...

var posts []Post
err := json.Unmarshal([]byte(content), &posts)

// Check err, do stuff with posts