2013-11-20 30 views
10

Tôi đang cố gắng để Unmarshal một số json để một đối tượng lồng nhau không được phân tích cú pháp nhưng chỉ được coi là một string hoặc []byte.json.Unmarshal lồng nhau đối tượng vào chuỗi hoặc [] byte

Vì vậy, tôi muốn nhận được như sau:

{ 
    "id" : 15, 
    "foo" : { "foo": 123, "bar": "baz" } 
} 

Unmarshaled thành:

type Bar struct { 
    Id int64 `json:"id"` 
    Foo []byte `json:"foo"` 
} 

tôi nhận được lỗi sau:

json: cannot unmarshal object into Go value of type []uint8 

playground demo

+1

Tại sao không sử dụng 'map [ chuỗi] giao diện {} '? Nó cũng có lợi thế là tái Marshalling đúng cách. –

Trả lời

19

Tôi nghĩ rằng những gì bạn đang tìm kiếm là loại RawMessage trong gói encoding/json.

Các trạng thái tài liệu:

type RawMessage []byte

RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.

Dưới đây là một ví dụ làm việc của việc sử dụng RawMessage:

package main 

import (
    "encoding/json" 
    "fmt" 
) 

var jsonStr = []byte(`{ 
    "id" : 15, 
    "foo" : { "foo": 123, "bar": "baz" } 
}`) 

type Bar struct { 
    Id int64   `json:"id"` 
    Foo json.RawMessage `json:"foo"` 
} 

func main() { 
    var bar Bar 

    err := json.Unmarshal(jsonStr, &bar) 
    if err != nil { 
     panic(err) 
    } 
    fmt.Printf("%+v\n", bar) 
} 

Output:

{Id:15 Foo:[123 32 34 102 111 111 34 58 32 49 50 51 44 32 34 98 97 114 34 58 32 34 98 97 122 34 32 125]}

Playground

+0

đó là chính xác những gì tôi muốn –

+2

Nói với bạn như vậy;). Vui mừng được giúp đỡ! – ANisus

2

Xác định một loại tiếng rít h thực hiện giao diện Unmarshaler cho phép bạn truy cập vào số []byte đang được phân tích cú pháp.

type Prefs []byte 

func (p *Prefs) UnmarshalJSON(b []byte) error { 
    *p = make(Prefs, len(b)) 
    copy(*p, b) 
    return nil 
} 

playground demo

2

Loại Foo là một bản đồ [chuỗi] chuỗi để xác định Foo một cách chính xác:

type Bar struct { 
    id int64 
    Foo map[string]string 
} 

nghĩ rằng sẽ làm việc tốt hơn

+1

Vì vậy, '[] bytes' ->' Unmarshal' -> 'map [string] giao diện {}' -> 'Marshal' ->' string' ... tại sao? –

-1

Sau một chút mày mò tôi' ve thấy rằng trong bản demo sân chơi của bạn vấn đề lớn nhất là typecasting của json vào một byte []. Để xem ý tôi là gì, hãy xem một sân chơi này: http://play.golang.org/p/M0706KCZbh

Nếu bạn chạy nó, bạn sẽ nhận thấy byte [] giữa lát được sắp xếp và lát cắt khác nhau quanh điểm của 'Prefs' biến.

json marshaled từ struct

[34 105 100 123 34 58 49 53 44 34 112 114 101 102 115 34 58 34 101 121 65 105 90 ...

định kiểu [] byte

[123 34 105 100 34 58 49 53 44 34 112 114 101 102 115 34 58 123 34 102 111 111 34 ...

Tôi đã xóa không gian trắng để thử và làm cho nó xếp hàng càng nhiều càng tốt. Chính takeaway từ này là typecasting không sản xuất các kết quả tương tự như chạy dữ liệu thông qua phương pháp json.Marshal và để thực hiện công việc này, bạn sẽ cần một loại tùy chỉnh để xử lý unmarshaling những gì các gói json không nhận ra.

+0

Tôi nghĩ ví dụ này truyền đạt tốt hơn những gì bạn đang nói http://play.golang.org/p/1XFn6zqME8. Tuy nhiên, nó không thực sự trả lời câu hỏi. –

Các vấn đề liên quan