2015-09-22 11 views
5

Załóżmy mam struct jakGo: Kiedy zostanie wyświetlony błąd powrotu json.Unmarshal do struct?

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

Następnie w głównym mam kod

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

najwyraźniej powyższy kod produkować nil błąd, niezależnie od formatu JSON jest inna. Kiedy funkcja json.Unmarshal() zwróci błąd w Go?

+1

Chcesz zrobić przykład, który działa, lub przynajmniej kompiluje, [jak to] (http://play.golang.org/p/ywOPSds8zQ). 'Unmarshal' zwróci błąd, gdy wejście nie będzie poprawne JSON (np. Zmień' false' na 'hello' lub usuń klamrę zamykającą). – twotwotwo

+0

To wszystko open source, zawsze możesz też sprawdzić implementację Unmarshal: https://golang.org/src/encoding/json/decode.go?s=2621:2669#L64 (i checkValid: https://golang.org /src/encoding/json/scanner.go?s=732:781#L16) –

Odpowiedz

14

Dekoder JSON nie zgłasza błędu, jeśli wartości w źródle nie odpowiadają wartościom w tarczy. Na przykład nie jest to błąd, jeśli źródło zawiera pole "status", ale cel nie.

Funkcja unmarshal nie zwracać błędy w innych sytuacjach: Błąd

składnia

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 

Niezgodność typu

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

więcej przykładów kiedy json.Unmarshal() zwraca błąd (oprócz specyfikacji Ying nieprawidłowy JSON)

Określanie nil lub empty plaster:

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

Określanie non-wskaźnik unmarshal na:

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

Określanie nil jako wskaźnik docelowy:

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

Określanie numerów JSON th at spowoduje przepełnienie typu celu. Powołując się na dokument z json.Unmarshal():

Jeśli wartość JSON nie jest odpowiedni dla danego typu docelowym lub jeżeli liczba JSON przelewa typ docelowy, unmarshal pomija tej dziedzinie i uzupełnia unmarshalling najlepiej jak to możliwe. Jeśli nie napotkamy poważniejszych błędów, Unmarshal zwraca UnmarshalTypeError opisujący najwcześniejszy taki błąd.

Aby to wykazać:

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

Aby dodać odpowiedź icza, można również uzyskać błąd, jeśli spróbujesz unmarshal do wpisywanych zerowej wskaźnika. Może się to zdarzyć, gdy na przykład utworzysz kawałek wskaźników do określonego typu, a następnie spróbuj wyrzucić z niej konkretny jeden z tych wskaźników.

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) 
Powiązane problemy