แปลง JSON เป็น Go Struct
สร้าง Go structs จาก JSON
อินพุต JSON
เอาต์พุต Go
การแปลง JSON เป็น Go คืออะไร?
การแปลง JSON เป็น Go คือกระบวนการสร้างนิยามประเภทของ Go จากข้อมูล JSON ดิบ เพื่อให้ทำงานร่วมกับ package encoding/json ใน standard library ของ Go ได้ เนื่องจาก Go เป็นภาษาที่กำหนดประเภทอย่างชัดเจน ทุก field ใน JSON จึงต้องมี struct field ที่สอดคล้องกัน พร้อมประเภทที่ถูกต้องและ struct tag ที่บอก serializer ว่าควรแมปกับ JSON key ใด การเขียนนิยามเหล่านี้ด้วยมือสำหรับ API responses ที่ขนาดใหญ่หรือซ้อนกันหลายชั้นเป็นงานที่ช้าและเกิดข้อผิดพลาดได้ง่าย
Package encoding/json ซึ่งกำหนดไว้ใน Go specification ตั้งแต่ Go 1.0 ใช้ reflection เพื่อจับคู่ JSON keys กับ exported struct fields การจับคู่นี้ไม่คำนึงถึงตัวพิมพ์ใหญ่เล็กโดยค่าเริ่มต้น แต่การกำหนด json struct tags อย่างชัดเจนถือเป็นมาตรฐาน เพราะช่วยลดความกำกวมและทำให้ใช้แบบแผนการตั้งชื่อ PascalCase ของ Go ได้ ในขณะที่ JSON ยังคงอยู่ในรูปแบบ camelCase หรือ snake_case เครื่องมือแปลงอัตโนมัติจะอ่าน JSON ของคุณ อนุมานประเภท Go จากค่าต่าง ๆ และสร้างนิยาม struct พร้อม tags ที่ถูกต้อง
ระบบประเภทของ Go แมปกับ JSON ได้ตรงไปตรงมา ค่าสตริงกลายเป็น string บูลีนกลายเป็น bool จำนวนเต็มกลายเป็น int และจำนวนทศนิยมกลายเป็น float64 JSON objects ที่ซ้อนกันกลายเป็น structs ที่มีชื่อแยกต่างหาก และ arrays กลายเป็น slices ช่องว่างเดียวคือ null: Go ไม่มีประเภท nullable สากล ดังนั้นค่า null มักกลายเป็น pointer types (*string, *int) หรือ interface{} เครื่องมือสร้างจัดการทั้งหมดนี้ได้ภายในเสี้ยววินาที
ทำไมต้องใช้เครื่องมือแปลง JSON เป็น Go?
การกำหนด Go structs จาก JSON ด้วยมือหมายความว่าต้องนับวงเล็บปีกกา เดาประเภท และเขียน tags ใหม่ทุกครั้งที่ API เปลี่ยนแปลง เครื่องมือแปลงช่วยขจัดความยุ่งยากเหล่านั้น
กรณีใช้งาน JSON เป็น Go
ตารางการแมปประเภท JSON เป็น Go
Package encoding/json ปฏิบัติตามกฎเฉพาะเมื่อแมปค่า JSON กับประเภท Go ตารางด้านล่างแสดงการแมปเริ่มต้นและทางเลือกที่พบบ่อย คอลัมน์ "Default" คือสิ่งที่เครื่องมือสร้างส่วนใหญ่ผลิตออกมา คอลัมน์ "Alternative" แสดงประเภทที่คุณอาจเลือกตามความต้องการของคุณ เช่น int64 สำหรับ IDs ขนาดใหญ่ หรือ pointer types สำหรับ nullable fields
| ประเภท JSON | ตัวอย่าง | Default | Alternative |
|---|---|---|---|
| string | "hello" | string | string |
| number (integer) | 42 | int | int64 |
| number (float) | 3.14 | float64 | float64 |
| boolean | true | bool | bool |
| null | null | interface{} | *string / *int |
| object | {"k": "v"} | struct | struct |
| array of strings | ["a", "b"] | []string | []string |
| array of objects | [{"id": 1}] | []Item | []Item |
| mixed array | [1, "a"] | []interface{} | []interface{} |
คู่มืออ้างอิง Go JSON Struct Tag
Struct tags ควบคุมวิธีที่ encoding/json ทำ serialization และ deserialization ของ fields json tag เป็น tag ที่พบบ่อยที่สุด แต่คุณสามารถรวมกับ tags อื่น ๆ (db, yaml, xml) ใน field เดียวกันได้ ไวยากรณ์ของ tag คือสตริงที่คั่นด้วย backtick หลังประเภทของ field นี่คือตัวเลือก json tag ที่ encoding/json รองรับ
| Tag | พฤติกรรม | กรณีใช้งาน |
|---|---|---|
| json:"name" | Maps struct field to JSON key "name" | Always generated |
| json:"name,omitempty" | Omits field from output if zero value | Optional fields |
| json:"-" | Field is never serialized or deserialized | Internal fields |
| json:"name,string" | Encodes int/bool as JSON string | String-encoded numbers |
json.Unmarshal กับ json.NewDecoder
Go มีสองวิธีในการถอดรหัส JSON ได้แก่ json.Unmarshal สำหรับ byte slices และ json.NewDecoder สำหรับ io.Reader streams ทั้งสองใช้กฎ struct tag เดียวกัน แต่แตกต่างกันในการเลือกใช้งาน
ตัวอย่างโค้ด
ตัวอย่างเหล่านี้แสดงวิธีใช้ Go structs ที่สร้างจาก JSON ในโปรแกรมจริง รวมถึงวิธีสร้างจากภาษาอื่น ๆ ตัวอย่าง Go ใช้ encoding/json จาก standard library
package main
import (
"encoding/json"
"fmt"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
IsActive bool `json:"is_active"`
Tags []string `json:"tags"`
}
func main() {
data := []byte(`{"id":1,"name":"Alice","email":"alice@example.com","is_active":true,"tags":["admin","editor"]}`)
var user User
if err := json.Unmarshal(data, &user); err != nil {
panic(err)
}
fmt.Println(user.Name) // → Alice
fmt.Println(user.Tags) // → [admin editor]
}// JSON response from API — this is the shape you'd convert to Go:
const res = await fetch("https://api.example.com/users/1");
const user = await res.json();
// user → { "id": 1, "name": "Alice", "email": "alice@example.com" }
// Equivalent Go struct:
// type User struct {
// ID int `json:"id"`
// Name string `json:"name"`
// Email string `json:"email"`
// }import json
def json_to_go(data: dict, name: str = "Root") -> str:
lines = [f"type {name} struct {{"]
type_map = {str: "string", int: "int", float: "float64", bool: "bool"}
for key, value in data.items():
go_type = type_map.get(type(value), "interface{}")
field = key.title().replace("_", "") # snake_case → PascalCase
lines.append(f'\t{field} {go_type} `json:"{key}"`')
lines.append("}")
return "\n".join(lines)
data = json.loads('{"user_name": "Alice", "age": 30, "verified": true}')
print(json_to_go(data))
# type Root struct {
# UserName string `json:"user_name"`
# Age int `json:"age"`
# Verified bool `json:"verified"`
# }package main
import (
"encoding/json"
"fmt"
"strings"
)
type Event struct {
Type string `json:"type"`
Payload string `json:"payload"`
}
func main() {
stream := strings.NewReader(`{"type":"click","payload":"btn-1"}
{"type":"scroll","payload":"page-2"}`)
dec := json.NewDecoder(stream)
for dec.More() {
var ev Event
if err := dec.Decode(&ev); err != nil {
break
}
fmt.Printf("%s: %s\n", ev.Type, ev.Payload)
}
// → click: btn-1
// → scroll: page-2
}