私のような構造を持っていると仮定します
type A struct{
name string`json:"name"`
}
次に、メインにコードがあります
var jsonString string = `{"status":false}`
var a A
error := json.Unmarshal([]byte(jsonString),&a)
上記のコードは、json形式が異なっていても、明らかにnilエラーを生成します。 json.Unmarshal()はいつGoでエラーを返しますか?
ソースの値がターゲットの値に対応していない場合、JSONデコーダーはエラーを報告しません。たとえば、ソースに「ステータス」フィールドが含まれていても、ターゲットには含まれていなくてもエラーではありません。
Unmarshal関数は、他の状況ではエラーを返します。
構文エラー
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
型の不一致
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
json.Unmarshal()
がエラーを返す場合のその他の例(無効なJSONを指定する以外に):
nil
またはempty
スライスの指定:
_i := 0
err := json.Unmarshal(nil, &i)
fmt.Println(err) // unexpected end of JSON input
_
非マーシャリングする非ポインターの指定:
_err = json.Unmarshal([]byte(`{"name":"a"}`), i)
fmt.Println(err) // json: Unmarshal(non-pointer int)
_
ターゲットポインターとしてnil
を指定:
_err = json.Unmarshal([]byte(`{"name":"a"}`), nil)
fmt.Println(err) // json: Unmarshal(nil)
_
ターゲットタイプをオーバーフローするJSON番号を指定します。 json.Unmarshal()
のドキュメントを引用:
JSON値が特定のターゲットタイプに適切でない場合、またはJSON番号がターゲットタイプをオーバーフローする場合、Unmarshalはそのフィールドをスキップし、アンマーシャリングを可能な限り完了します。深刻なエラーが発生しなくなった場合、Unmarshalは、そのような最も早いエラーを説明するUnmarshalTypeErrorを返します。
これを実証するには:
_var j int8
err = json.Unmarshal([]byte(`1112`), &j)
fmt.Println(err) // json: cannot unmarshal number 1112 into Go value of type int8
_
または、RFC3339タイムスタンプではない_time.Time
_として何かを解析しようとした場合:
_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"
_
Iczaの答えに追加するために、型指定されたnilポインターに非整列化しようとすると、エラーが発生することもあります。これは、たとえば、特定の型へのポインターのスライスを作成し、それらのポインターの特定の1つにアンマーシャリングしようとした場合に発生する可能性があります。
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)