JSON thành cấu trúc

Tiếp theo

Dán một mẫu JSON để nhận các định nghĩa cấu trúc Go có thể phân tích chính xác bằng encoding/json. Các trường sẽ được xuất ra dưới dạng CamelCase, được gắn nhãn với các khóa JSON gốc; khi giá trị có thể là null thì chúng được chuyển thành con trỏ; các đối tượng lồng ghép sẽ được định nghĩa dưới dạng cấu trúc riêng biệt với tên riêng.

Cách chuyển đổi JSON thành cấu trúc Go

  1. 1

    Dán JSON

    Chỉ cần một mẫu là đủ; sử dụng nhiều mẫu sẽ giúp cải thiện khả năng suy luận đối với các giá trị có thể bị bỏ sót (nullable).

  2. 2

    Chọn tên

    Đối với các trường được xuất, PascalCase là quy ước của ngôn ngữ Go. Hãy chọn kiểu viết tắt phù hợp (ví dụ: `URL` so với `Url`, hoặc `ID` so với `Id`).

  3. 3

    Chọn chiến lược tùy chọn

    Hãy sử dụng con trỏ cho các trường có thể là null (phương pháp phổ biến nhất) hoặc thẻ `omitempty`.

  4. 4

    Sao chép các cấu trúc

    Một cấu trúc gốc cùng các cấu trúc con được đặt bên trong. Dán vào tệp `.go` và chọn `go build`.

Ví dụ về kết quả đầu ra

Đối với:

{ "first_name": "Alice", "age": 30, "email": null, "tags": ["admin"] }

Kết quả đầu ra:

type User struct {
    FirstName string   `json:"first_name"`
    Age       int      `json:"age"`
    Email     *string  `json:"email"`
    Tags      []string `json:"tags"`
}

Xác định kiểu dữ liệu

Giá trị JSON Loại Go
chuỗi văn bản string
số nguyên int hoặc int64
Số (dạng thập phân) float64
boolean bool
null (khi có anh chị em không phải null) *T (con trỏ)
mảng []T
đối tượng cấu trúc có tên
mảng hỗn hợp []interface{}

Các cách đặt tên mà bộ tạo tuân theo

  • Các chữ viết tắt được viết hoa: idID, urlURL, api_keyAPIKey. Điều này phù hợp với phong cách được khuyến nghị của Go (và các quy tắc liên quan đến go vet/staticcheck).
  • Các trường từ định dạng JSON Snake Case sang định dạng Pascal Case: first_nameFirstName.
  • Các viết tắt đơn từ được giữ nguyên: IP vẫn là IP; HTTP vẫn là HTTP.
  • Thẻ JSON: json:"first_name" giữ nguyên khóa gốc để quá trình mã hóa và giải mã diễn ra một cách thuận lợi.

Các trường tùy chọn: con trỏ hoặc omitempty?

Chiến lược Áp dụng khi
Chỉ báo (*T) Bạn cần phân biệt rõ giữa “vắng mặt” và “giá trị bằng không”.
omitempty Bạn chỉ cần bỏ qua các giá trị bằng 0 khi thực hiện thao tác marshal; khi unmarshal, giá trị 0 sẽ được lưu lại nếu không có giá trị tương ứng
Không có Trường này luôn tồn tại và các giá trị bằng không có ý nghĩa

Bộ tạo sẽ mặc định sử dụng con trỏ + omitempty đối với mọi giá trị được coi là null; hãy điều chỉnh theo ngữ nghĩa cụ thể của bạn.

Các lỗi phổ biến

  • Khi giá trị số nguyên trong JSON vượt quá giới hạn của MaxInt32 trên hệ thống mục tiêu 32 bit, hãy sử dụng int; đối với các giá trị lớn đã biết, hãy sử dụng int64.
  • Đặt lại thứ tự và mất thứ tự các khóa chính: encoding/json phát các khóa theo thứ tự được xác định trong phần mô tả trường, chứ không phải theo thứ tự JSON gốc. Hãy sắp xếp thủ công nếu cần kết quả đầu ra chuẩn hóa.
  • Các mảng có hình dạng hỗn hợp: []interface{} mất tính an toàn về kiểu dữ liệu; hãy sử dụng các kiểu dữ liệu hợp nhất với trường phân biệt type thay thế.
  • Bỏ quên trường omitempty trong các trường tùy chọn: Nếu không có trường này, các trường tùy chọn sẽ được mã hóa dưới dạng "foo": null thay vì bị bỏ qua.

Câu hỏi thường gặp

Hãy sử dụng con trỏ khi cần phân biệt giữa trường “không có” và trường “giá trị bằng 0”. Sử dụng omitempty nếu giá trị 0 không phải là giá trị hợp lệ trong nghiệp vụ ("", 0, false luôn có nghĩa là “bỏ qua phần này”). Nhiều nhóm chọn một trong hai cách và áp dụng đồng nhất trên toàn bộ cơ sở mã nguồn.

Mỗi đối tượng lồng vào nhau sẽ trở thành một khai báo cấu trúc có tên riêng biệt (ví dụ: UserAddress). Các kiểu chỉ được tích hợp trực tiếp khi cấu trúc lồng vào rất nhỏ và chỉ được sử dụng một lần; nếu không, bạn sẽ nhận được các kiểu rõ ràng và có thể tái sử dụng được.

Đúng vậy. id trở thành ID, url trở thành URL, và api_key trở thành APIKey. Đây chính là yêu cầu của go vet và cũng là điều mà hầu hết các hướng dẫn phong cách viết Go đều khuyến nghị.

Bộ tạo sinh ra các đối tượng struct thông thường với thẻ tiêu chuẩn json:. Đối với các triển khai tùy chỉnh của UnmarshalJSON (ví dụ: dùng để biểu diễn ngày theo định dạng không phải ISO), hãy thêm chúng thủ công sau khi hoàn thành quá trình tạo.

Công cụ liên quan

Công cụ này có phiên bản bằng các ngôn ngữ khác