2015-09-22 12 views
5

Si supponga che ho una struttura comeVai: quando json.Unmarshal mostrerà l'errore di restituzione?

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

Poi, nel principale Ho codice

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

a quanto pare il codice qui sopra produrre un errore pari a zero, indipendentemente dal formato JSON è diverso. Quando json.Unmarshal() restituirà l'errore in Go?

+1

Volete fare un esempio che funzioni, o almeno compila, [come questo] (http://play.golang.org/p/ywOPSds8zQ). 'Unmarshal' restituirà un errore quando l'input non è valido JSON (come, cambia' false' in 'hello', o rimuovi la parentesi chiusa). – twotwotwo

+0

È tutto open source, puoi sempre controllare anche l'implementazione di Unmarshal: https://golang.org/src/encoding/json/decode.go?s=2621:2669#L64 (e checkValid: https://golang.org) /src/encoding/json/scanner.go?s=732:781#L16) –

risposta

14

Il decodificatore JSON non segnala un errore se i valori nella sorgente non corrispondono ai valori nella destinazione. Ad esempio, non è un errore se la fonte contiene il campo "stato", ma il bersaglio no.

La funzione Unmarshal fa restituire gli errori in altre situazioni: errore

Sintassi

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 

tipo non corrispondente

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

E altri esempi quando json.Unmarshal() restituisce un errore (inoltre specif ying un JSON valido):

Specifica di un nil o empty fetta:

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

Specifica di un non-puntatore unmarshal in:

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

Specifica nil come puntatore porta:

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

Specificare i numeri JSON th a traboccherebbe il tipo di bersaglio. Citando il doc di json.Unmarshal():

Se un valore JSON non è appropriato per un determinato tipo di bersaglio, o se un numero JSON trabocca il tipo di destinazione, Unmarshal salta quel campo e completa l'unmarshalling nel miglior modo possibile. Se non si verificano più errori gravi, Unmarshal restituisce un errore UnmarshalType che descrive il primo errore di questo tipo.

per dimostrare questo:

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

Per aggiungere alla risposta di icza, è anche possibile ottenere un errore se si tenta di Unmarshal in un puntatore nullo digitato. Questo può accadere se, ad esempio, si crea una porzione di puntatori a un particolare tipo, quindi si prova e unmarshal in un particolare di quei puntatori.

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)