4

I have this JSON data:

{
"InfoA" : [256,256,20000],
"InfoB" : [256,512,15000],
"InfoC" : [208,512,20000],
"DEFAULT" : [256,256,20000]
}

With JSON-to-Go, I get this Go type definition:

type AutoGenerated struct {
    InfoA   []int `json:"InfoA"`
    InfoB   []int `json:"InfoB"`
    InfoC   []int `json:"InfoC"`
    DEFAULT []int `json:"DEFAULT"`
}

With this code (play.golang.org)

package main

import (
    "encoding/json"
    "fmt"
    "os"
    "strings"
)

func main() {
    type paramsInfo struct {
        InfoA   []int `json:"InfoA"`
        InfoB   []int `json:"InfoB"`
        InfoC   []int `json:"InfoC"`
        DEFAULT []int `json:"DEFAULT"`
    }
    rawJSON := []byte(`{
"InfoA" : [256,256,20000],
"InfoB" : [256,512,15000],
"InfoC" : [208,512,20000],
"DEFAULT" : [256,256,20000]
}`)
    var params []paramsInfo
    err := json.Unmarshal(rawJSON, &params)
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }
}

I get error json: cannot unmarshal object into Go value of type []main.paramsInfo

I don't understand why. Can you help me?

1
  • What part of the error is confusing you? It tells you exactly the problem. Commented Nov 22, 2017 at 11:18

2 Answers 2

9

The JSON source is a single object, yet you try to unmarshal it into a slice. Change the type of params to paramsInfo (non-slice):

var params paramsInfo
err := json.Unmarshal(rawJSON, &params)
if err != nil {
    fmt.Println(err.Error())
    os.Exit(1)
}
fmt.Printf("%+v", params)

And with that the output (try it on the Go Playground):

{InfoA:[256 256 20000] InfoB:[256 512 15000] InfoC:[208 512 20000]
    DEFAULT:[256 256 20000]}
Sign up to request clarification or add additional context in comments.

3 Comments

How can I do without explictly declaring "InfoA ", "InfoAB", etc in structs ? I implemented a solution (play.golang.org/p/3NoMXoyOCU), but I got empty result. I don't see how it might be implemented.
@LeMoussel See this answer and this answer.
Solution: params2 := make(map[string][]int) _= json.Unmarshal(rawJSON, &params2) fmt.Printf("\nparams2: %+v", params2)
2

You are decoding a single JSON object but you are attempting to put it into the []paramsInfo slice.

It works fine when you decode JSON array of objects:

rawJSON := []byte(`[{
    "InfoA" : [256,256,20000],
    "InfoB" : [256,512,15000],
    "InfoC" : [208,512,20000],
    "DEFAULT" : [256,256,20000]
}]`)

(note the square brackets around your object)

By the way, in the if branch handling an error you don't need to call err.Error() to get the error string; fmt.Println(err) is sufficient and it's actually a Go idiom to use it like this. The implementation of fmt.Print* is taking care of handling the error type (contrary to print for example).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.