2015-09-22 7 views
5

nehme ich wieGo: Wann wird json.Unmarshal zu struct Fehler zurückgeben?

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

Dann in Haupt eine Struktur haben i Code

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

offenbar der Code über eine Null-Fehler erzeugen, unabhängig JSON-Format haben, ist anders. Wann wird json.Unmarshal() Fehler in Go zurückgeben?

+1

Sie wollen ein Beispiel machen, das funktioniert, oder zumindest kompiliert, [so] (http://play.golang.org/p/ywOPSds8zQ). 'Unmarshal' wird einen Fehler zurückgeben, wenn die Eingabe nicht gültig ist JSON (wie,' '' '' '' '' '' '' '' 'ändern, oder die 'close' Klammer entfernen). – twotwotwo

+0

Es ist alles Open Source, Sie können auch die Implementierung von Unmarshal überprüfen: https://golang.org/src/encoding/json/decode.go?s=2621:2669#L64 (und checkValid: https://golang.org /src/encoding/json/scanner.go?s=732:781#L16) –

Antwort

14

Der JSON-Decoder meldet keinen Fehler, wenn Werte in der Quelle nicht mit Werten im Ziel übereinstimmen. Zum Beispiel ist es kein Fehler, wenn die Quelle das Feld "Status" enthält, das Ziel jedoch nicht.

Die Abstellungs Funktion macht Fehler in anderen Situationen zurück:

Syntaxfehler

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

4

Und weitere Beispiele, wenn json.Unmarshal() einen Fehler zurückgibt (neben bestimmten Ying ein ungültiger JSON):

Angeben eines nil oder empty slice:

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

einen nicht-Pointer angeben unmarshal in:

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

nil als Zielzeiger spezifiziert wird:

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

Angeben von JSON-Nummern th bei würde der Zieltyp überlaufen. Unter Angabe des doc von json.Unmarshal():

Wenn ein JSON-Wert nicht angemessen für einen bestimmten Zieltyp ist, oder wenn eine JSON-Nummer des Zieltyp überläuft, springt Abstellungs das Feld und schließt das unmarshalling so gut er kann. Wenn keine ernsthaften Fehler mehr auftreten, gibt Unmarshal einen UnmarshalTypeError zurück, der den frühesten solchen Fehler beschreibt.

Um dies zu demonstrieren:

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

zu icza Antwort hinzuzufügen, können Sie auch eine Fehlermeldung erhalten, wenn Sie Abstellungs in einen typisierte Null-Zeiger versuchen. Dies kann passieren, wenn Sie beispielsweise eine Reihe von Zeigern zu einem bestimmten Typ machen und dann versuchen, in einen bestimmten dieser Zeiger zu entpacken.

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) 
Verwandte Themen