2015-09-22 17 views
5

iはGo:いつjson.Unmarshalが構造体にエラーを返しますか?

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

ような構造体があると、メインIにおいてコード

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

を有する見かけ上のコードがゼロエラーが発生し、関係なく、JSON形式が異なっています。 json.Unmarshal()はいつGoでエラーを返しますか?

+1

[好きな](http://play.golang.org/p/ywOPSds8zQ)という作品を作ったり、少なくともコンパイルしたりしたいとします。 'Unmarshal'は、入力が有効なJSON(' false'から 'hello'への変更、または閉じ括弧の削除など)でないときにエラーを返します。 – twotwotwo

+0

これはオープンソースなので、Unmarshalの実装もいつでもチェックできます:https://golang.org/src/encoding/json/decode.go?s=2621:2669#L64(およびcheckValid:https://golang.org) /src/encoding/json/scanner.go?s=732:781#L16) –

答えて

14

JSONデコーダは、ソース内の値がターゲット内の値に対応していない場合、エラーを報告しません。たとえば、ソースに「ステータス」フィールドが含まれていても、ターゲットには表示されない場合はエラーではありません。

非整列化機能は、他の状況でエラーが返されない:エラーを返し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 

playground example

4

そして、より多くの例を特定の英無効JSON):

err = json.Unmarshal([]byte(`{"name":"a"}`), i) 
fmt.Println(err) // json: Unmarshal(non-pointer int) 

がターゲットポインタとしてnilを指定:にアンマーシャルする非ポインタを指定

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

nil又はemptyスライスの指定

err = json.Unmarshal([]byte(`{"name":"a"}`), nil) 
fmt.Println(err) // json: Unmarshal(nil) 

JSON番号を指定するth atはターゲットタイプをオーバーフローします。 json.Unmarshal()のドキュメントを引用:JSON番号はターゲット・タイプをオーバーフローした場合

をJSON値が与えられた目標タイプに適していない場合、または、非整列化は、そのフィールドをスキップし、それができる最善のように非整列化が完了します。それ以上重大なエラーが発生しなければ、Unmarshalはこのようなエラーを最も早く記述するUnmarshalTypeErrorを返します。

はこれを実証するために:あなたが入力したNULLポインタに非整列化しようとした場合

var j int8 
err = json.Unmarshal([]byte(`1112`), &j) 
fmt.Println(err) // json: cannot unmarshal number 1112 into Go value of type int8 
1

がiczaの答えに追加するには、あなたはまた、エラーを取得することができます。これは、たとえば、特定の型へのポインタのスライスを作成し、それらのポインタのうちの特定のものにアンマーシャリングしようとする場合に発生します。

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) 
関連する問題