Tên khóa JSON chữ thường với JSON Marshal trong Go


175

Tôi muốn sử dụng "encoding/json"gói để sắp xếp một cấu trúc được khai báo trong một trong các gói đã nhập trong ứng dụng của tôi.

Ví dụ.:

type T struct {
    Foo int
}

Bởi vì nó được nhập, tất cả các trường có sẵn (xuất) trong cấu trúc bắt đầu bằng chữ in hoa. Nhưng tôi muốn có tên khóa viết thường:

out, err := json.Marshal(&T{Foo: 42})

sẽ cho kết quả

{"Foo": 42}

nhưng tôi muốn có được

{"foo": 42}

Có thể đi xung quanh vấn đề một cách dễ dàng?


5
@Zippoxer: Tôi muốn nói: một khóa trong giao thức giao tiếp máy khách / máy chủ được xác định nghiêm ngặt đối với các chữ cái viết thường. Chà, trong trường hợp của tôi thì không vấn đề gì vì tôi đã tự xác định giao thức .. nhưng ít nhất là trên lý thuyết? Nhưng, tôi biết chủ yếu là tôi dành quá nhiều thời gian cho một chi tiết nhỏ ngớ ngẩn.
ANisus

Đừng xin lỗi. Bạn không phải là người ngớ ngẩn, ngôn ngữ không chấp nhận thông số json đầy đủ là ngôn ngữ ngớ ngẩn (mặc dù vấn đề dễ dàng được giải quyết, như dưới đây).
Jehan

@ANisus: Tôi đọc sai câu hỏi của bạn như về tên khóa struct, không phải tên khóa JSON. Rút lại phiếu bầu.
Flimzy

Câu trả lời:


265

Có một cái nhìn vào các tài liệu để mã hóa / json.Marshal . Nó thảo luận về việc sử dụng các thẻ trường cấu trúc để xác định cách json được tạo được định dạng.

Ví dụ:

type T struct {
    FieldA int    `json:"field_a"`
    FieldB string `json:"field_b,omitempty"`
}

Điều này sẽ tạo JSON như sau:

{
    "field_a": 1234,
    "field_b": "foobar"
}

8
Thẻ trường? Ôi trời .. Tôi đã bỏ lỡ toàn bộ phần này khi tìm kiếm trong các tài liệu. Tôi đã tìm kiếm cờ, chức năng hoặc một số cài đặt khác. Vâng, đây là câu trả lời chính xác mà tôi đang tìm kiếm! Và ngoài ra, tôi có một khái niệm Go mới để tìm hiểu về: thẻ trường :)
ANisus

Chúng khá tiện dụng. Bạn có thể truy cập chúng trong thời gian chạy thông qua reflectgói.
jimt

Vâng, khi làm việc với sự phản chiếu tôi thấy việc có cách thêm dữ liệu meta vào một trường có thể là một điều tuyệt vời như thế nào! Btw, chỉ cần thử câu trả lời. Hoạt động như một lá bùa.
ANisus

5
Tôi mới bắt đầu nguyền rủa ngôn ngữ cờ vây - thật là ngu ngốc, tại sao họ lại tạo ra các trường có chữ thường trong JSON được tạo, v.v. Sau đó, tôi đã xem qua chủ đề này và nghĩ rằng "OMG Thật tuyệt vời !!!". Tôi thậm chí đã nhảy và giải thích cho bạn gái của mình tại sao tôi rất phấn khích: D Thật tuyệt vời :)))
nyxz

11
Hãy chắc chắn rằng không có khoảng trắng giữa dấu hai chấm và dấu ngoặc kép đầu tiên của thẻ! Sử dụng json:"some_tag"thay vì json: "some_tag". Tôi đã nhận được một chút bởi điều này trong một thời gian.
David Morales

8

Bạn có thể tạo cấu trúc của riêng mình bằng các khóa mà bạn muốn xuất và cung cấp cho chúng các thẻ json thích hợp cho tên chữ thường. Sau đó, bạn có thể sao chép cấu trúc mong muốn vào của bạn trước khi mã hóa nó dưới dạng JSON. Hoặc nếu bạn không muốn làm phiền với việc tạo cấu trúc cục bộ, bạn có thể tạo map[string]interface{}và mã hóa nó.


Điều ngớ ngẩn là gói khác (chứa các loại) thực sự là của tôi. Nhưng, vâng, tôi có lẽ đã nhìn chằm chằm vào sự thật rằng nó phải là một cấu trúc. Sử dụng một map[string]interface{}sẽ hoạt động miễn là tôi không kết thúc với các đối tượng / cấu trúc lồng nhau
ANisus

1
@ANisus: Ồ, câu trả lời của tôi được khẳng định là bạn không kiểm soát được định nghĩa của struct. Câu trả lời của jimt chắc chắn là những gì bạn muốn.
Lily Ballard

Vâng, tôi không rõ liệu nó có phải là một gói bên ngoài hay không. Nhưng câu trả lời của bạn vẫn có liên quan và hữu ích trong các trường hợp khi bạn không kiểm soát các định nghĩa.
ANisus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.