2015-09-22 33 views
5

Giả sử tôi có một struct nhưGo: Khi nào json.Unmarshal sẽ trả về lỗi cấu trúc?

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

Sau đó, trong chính tôi có mã

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

dường như mã trên tạo ra một lỗi bằng không, bất kể định dạng json là khác nhau. Khi nào json.Unmarshal() trả về lỗi trong Go?

+1

Bạn muốn tạo ví dụ hoạt động hoặc ít nhất là biên dịch, [như thế này] (http://play.golang.org/p/ywOPSds8zQ). 'Unmarshal' sẽ trả về lỗi khi đầu vào không hợp lệ JSON (như, thay đổi' false' thành 'hello', hoặc loại bỏ dấu ngoặc nhọn). – twotwotwo

+0

Đó là tất cả nguồn mở, bạn luôn có thể kiểm tra quá trình triển khai của Unmarshal: https://golang.org/src/encoding/json/decode.go?s=2621:2669#L64 (và checkValid: https://golang.org /src/encoding/json/scanner.go?s=732:781#L16) –

Trả lời

14

Bộ giải mã JSON không báo cáo lỗi nếu giá trị trong nguồn không tương ứng với giá trị trong mục tiêu. Ví dụ, nó không phải là một lỗi nếu nguồn chứa trường "trạng thái", nhưng mục tiêu thì không.

Chức năng unmarshal không trả lại lỗi trong các tình huống khác:

Cú pháp lỗi

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 

không phù hợp Loại

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

Và nhiều ví dụ khi json.Unmarshal() trả về một lỗi (bên cạnh specif ying một JSON không hợp lệ):

Chỉ định nil hoặc empty lát:

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

Xác định một tổ chức phi-con trỏ đến unmarshal thành:

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

Xác định nil như con trỏ mục tiêu:

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

Chỉ định số JSON thứ tại sẽ tràn loại mục tiêu. Trích dẫn doc của json.Unmarshal():

Nếu một giá trị JSON là không thích hợp cho một loại mục tiêu nhất định, hoặc nếu một số JSON tràn các loại mục tiêu, unmarshal bỏ qua lĩnh vực đó và hoàn thành unmarshalling như tốt nhất có thể. Nếu không gặp phải lỗi nghiêm trọng nào khác, Unmarshal trả về một UnmarshalTypeError mô tả lỗi sớm nhất như vậy.

Để chứng minh điều này:

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

Để thêm vào câu trả lời của icza, bạn cũng có thể nhận được một lỗi nếu bạn cố gắng unmarshal vào một con trỏ nil gõ. Điều này có thể xảy ra nếu, ví dụ, bạn thực hiện một lát con trỏ đến một loại cụ thể, sau đó thử và unmarshal vào một trong những đặc biệt của những con trỏ.

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) 
Các vấn đề liên quan