Go: When will json.Unmarshal for a structure return error?

Suppose I have a structure like

type A struct{ name string`json:"name"` } 

Then in the main I have code

 var jsonString string = `{"status":false}` var a A error := json.Unmarshal([]byte(jsonString),&a) 

it is obvious that the code above generates a nil error, regardless of the json format. When will json.Unmarshal () return an error in Go?

+8
source share
3 answers

The JSON decoder does not report an error if the values ​​in the source do not match the values ​​in the target. For example, this is not an error if the source contains a status field, but the target is not specified.

The Unmarshal function returns 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 

Type mismatch

 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 

playground example

+16
source

And more examples when json.Unmarshal() returns an error (in addition to indicating an invalid JSON):

Specifying a nil or empty fragment:

 i := 0 err := json.Unmarshal(nil, &i) fmt.Println(err) // unexpected end of JSON input 

Indication of no pointer to unmarshal in:

 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) 

Specifies the JSON numbers that will overflow the target type. json.Unmarshal() doc json.Unmarshal() :

If the JSON value is not suitable for the target type, or if the JSON number overflows the target type, Unmarshal skips this field and completes the dismantling as best as possible. If no more serious errors are found, Unmarshal returns a 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 analyze something like time. 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" 
+7
source

To add icza to the answer, you may also get an error message if you try to use Unmarshal in a nil typed pointer. This can happen if, for example, you create a fragment of pointers for a certain type, then try and unmount it into a specific one of these pointers.

 package main import ( "fmt" "encoding/json" ) type Example struct {Name string} func main() { exs := make([]*Example, 5) err := json.Unmarshal([]byte(`{"name":"jane"}`), exs[0]) fmt.Println(err) } // json: Unmarshal(nil *main.Example) 
+2
source

Source: https://habr.com/ru/post/1231987/


All Articles