Assume i have a struct like
type A struct{
name string`json:"name"`
}
Then in main i have code
var jsonString string = `{"status":false}`
var a A
error := json.Unmarshal([]byte(jsonString),&a)
apparently the code above produce a nil error, regardless the json format is different. When will json.Unmarshal() return error in Go?
To unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice.
Go's terminology calls marshal the process of generating a JSON string from a data structure, and unmarshal the act of parsing JSON to a data structure.
Golang Unmarshal Unmarshal is the contrary of marshal. It allows you to convert byte data into the original data structure. In go, unmarshaling is handled by the json. Unmarshal() method.
In Golang, struct data is converted into JSON and JSON data to string with Marshal() and Unmarshal() method. The methods returned data in byte format and we need to change returned data into JSON or String. In our previous tutorial, we have explained about Parsing JSON Data in Golang.
The JSON decoder does not report an error if values in the source do not correspond to values in the target. For example, it's not an error if the source contains the field "status", but the target does not.
The Unmarshal function does return errors in other situations.
Syntax error
type A struct {
Name string `json:"name"`
}
data = []byte(`{"name":what?}`)
err = json.Unmarshal(data, &a)
fmt.Println(err) // prints character 'w' looking for beginning of value
JSON value not representable by target type:
data := []byte(`{"name":false}`)
type B struct {
Name string `json:"name"`
}
var b B
err = json.Unmarshal(data, &b)
fmt.Println(err) // prints cannot unmarshal bool into Go value of type string
(This is one example of where the value cannot be represented by target type. There are more.)
playground example
And more examples when json.Unmarshal()
returns an error (besides specifying an invalid JSON):
Specifying a nil
or empty
slice:
i := 0
err := json.Unmarshal(nil, &i)
fmt.Println(err) // unexpected end of JSON input
Specifying a non-pointer to unmarshal into:
err = json.Unmarshal([]byte(`{"name":"a"}`), i)
fmt.Println(err) // json: Unmarshal(non-pointer int)
Specifying nil
as the target pointer:
err = json.Unmarshal([]byte(`{"name":"a"}`), nil)
fmt.Println(err) // json: Unmarshal(nil)
Specifying JSON numbers that would overflow the target type. Quoting the doc of json.Unmarshal()
:
If a JSON value is not appropriate for a given target type, or if a JSON number overflows the target type, Unmarshal skips that field and completes the unmarshalling as best it can. If no more serious errors are encountered, Unmarshal returns an UnmarshalTypeError describing the earliest such error.
To demonstrate this:
var j int8
err = json.Unmarshal([]byte(`1112`), &j)
fmt.Println(err) // json: cannot unmarshal number 1112 into Go value of type int8
Or when trying to parse something as a time.Time
which is not an RFC3339 timestamp:
var t time.Time
err = json.Unmarshal([]byte(`"xx"`), &t)
fmt.Println(err) // parsing time ""xx"" as ""2006-01-02T15:04:05Z07:00"": cannot parse "xx"" as "2006"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With