2013-01-06 39 views
7

Tôi có cấu trúc với thành viên []uint8 và tôi đang viết nó với json.Marshal. Vấn đề là, nó giải thích các uint8 s là char s và nó xuất ra một chuỗi chứ không phải là một dãy số.Làm thế nào để sắp xếp một mảng byte/uint8 dưới dạng mảng json trong Go?

Tôi có thể làm việc này nếu đó là []int, nhưng tôi không muốn phân bổ và sao chép các mục nếu tôi có thể tránh được. Tôi có thể?

+0

Như tôi đã nói trong câu hỏi, tôi đang sử dụng 'json.Marshal'. Câu hỏi của tôi không phải là về 'fmt', nó là về thư viện' json'. – Joe

+0

(Tôi đã có một bình luận hỏi về cách tôi đã xuất ra nó, tác giả đã xóa nó sau khi tôi trả lời. Có thể cũng giữ cho phản ứng của tôi.) – Joe

Trả lời

13

Theo số docs, []byte sẽ được mã hóa dưới dạng chuỗi Base64.

"Array và lát giá trị mã hóa như mảng JSON, ngoại trừ việc [] byte mã hóa như là một chuỗi base64 mã hóa, và một lát bằng không mã hóa là đối tượng JSON null."

Vì vậy, tôi nghĩ rằng bạn có thể cần phải thực hiện struct của bạn thực hiện các giao diện Marshaler bằng cách thực hiện MarshalJSON phương pháp riêng của mình mà làm cho một mã hóa mảng JSON mong muốn nhiều hơn từ các []uint8 của bạn.

Hãy ví dụ này:

import "fmt" 
import "encoding/json" 
import "strings" 

type Test struct { 
    Name string 
    Array []uint8 
} 

func (t *Test) MarshalJSON() ([]byte, error) { 
    var array string 
    if t.Array == nil { 
     array = "null" 
    } else { 
     array = strings.Join(strings.Fields(fmt.Sprintf("%d", t.Array)), ",") 
    } 
    jsonResult := fmt.Sprintf(`{"Name":%q,"Array":%s}`, t.Name, array) 
    return []byte(jsonResult), nil 
} 

func main() { 
    t := &Test{"Go", []uint8{'h', 'e', 'l', 'l', 'o'}} 

    m, err := json.Marshal(t) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%s", m) // {"Name":"Go","Array":[104,101,108,108,111]} 
} 

http://play.golang.org/p/Tip59Z9gqs


Hoặc có thể là một ý tưởng tốt hơn sẽ được tạo ra một loại mới có []uint8 as type cơ bản của nó, làm cho điều đó loại một Marshaler, và sử dụng loại đó trong cấu trúc của bạn.

import "fmt" 
import "encoding/json" 
import "strings" 

type JSONableSlice []uint8 

func (u JSONableSlice) MarshalJSON() ([]byte, error) { 
    var result string 
    if u == nil { 
     result = "null" 
    } else { 
     result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",") 
    } 
    return []byte(result), nil 
} 

type Test struct { 
    Name string 
    Array JSONableSlice 
} 

func main() { 
    t := &Test{"Go", []uint8{'h', 'e', 'l', 'l', 'o'}} 

    m, err := json.Marshal(t) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Printf("%s", m) // {"Name":"Go","Array":[104,101,108,108,111]} 
} 

http://play.golang.org/p/6aURXw8P5d

+0

Brilliant. Tôi nghĩ rằng tùy chọn thứ hai là một chút tương lai hơn bằng chứng. Cảm ơn rất nhiều. – Joe

+0

@Joe: Bạn được chào đón. Và tôi đã cập nhật để làm cho nó hoàn chỉnh hơn một chút bằng cách xử lý một slice 'nil' là' null'. –

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