Pelajaran modul (5/5)
`pengkodean/json`
encoding/json adalah paket kanonik untuk membuat serialisasi struct Go ke JSON dan sebaliknya. Mengetahui konvensi dan kendalanya akan menghemat waktu berjam-jam untuk melakukan debug pada API dan file konfigurasi.
Marsekal dan Unmarshal
Dua fungsi utama:
data, err := json.Marshal(v) // Go → []byte JSON
err = json.Unmarshal(data, &v) // JSON → Go (pass a pointer!)type User struct {
Name string
Email string
}
u := User{Name: "Ada", Email: "ada@example.com"}
b, _ := json.Marshal(u)
fmt.Println(string(b))
// {"Name":"Ada","Email":"ada@example.com"}
var back User
_ = json.Unmarshal(b, &back)Untuk keluaran yang menjorok ke dalam (dapat dibaca manusia) gunakan json.MarshalIndent(v, "", " ").
Hanya bidang yang diekspor
json.Marshal membuat serial hanya kolom yang diekspor (Huruf Besar). Bidang pribadi diabaikan secara diam-diam:
type U struct {
Name string // exported → serialized
age int // private → ignored
}Tag struktur: mengontrol nama dan opsi
Tag json:"..." mengontrol nama, penghilangan, dan tipe dalam output:
type User struct {
Name string `json:"name"` // rename
Email string `json:"email,omitempty"` // omit if zero value
Private string `json:"-"` // never serialized
ID int `json:"id,string"` // number as string
}Opsi yang paling sering digunakan:
,omitempty— menghilangkan kolom jika nilai nol (0, "", nil, irisan/peta kosong).,-— tidak pernah diserialkan/dideserialisasi.,string— membungkus angka/bool sebagai string (berguna untuk ID JS).
Decoder/Encoder untuk streaming
Saat bekerja dengan io.Reader/io.Writer (badan HTTP, file besar) gunakan Decoder dan Encoder alih-alih memuat semua yang ada di memori:
dec := json.NewDecoder(resp.Body)
var users []User
if err := dec.Decode(&users); err != nil {
return err
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(users)Decoder juga mendukung dec.Token() untuk penguraian streaming sepotong demi sepotong dan dec.DisallowUnknownFields() untuk menolak JSON dengan kunci yang tidak terduga (berguna untuk validasi input).
Peta umum dan any
Jika Anda tidak mengetahui skemanya, deserialisasikan ke map[string]any:
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])Nilai akan memiliki tipe dinamis (string, float64 untuk angka, []any, map[string]any, bool, nil).
Kesalahan umum
- Lupa
&:json.Unmarshal(data, v)tidak mengisi apa pun; Anda membutuhkan&v. - Mendekode struct dengan kolom nihil: untuk menghindari kepanikan, periksa
errSEBELUM membaca kolom. - Jenis yang tidak kompatibel: membatalkan serialisasi angka menjadi string atau sebaliknya akan mengembalikan
*json.UnmarshalTypeError.
Latihan
Buat serial struct u ke JSON dengan json.Marshal dan cetak hasilnya sebagai string.
Solusi tersedia setelah 3 upaya
Deserialisasi `{"Name":"Ada"}` ke dalam struct U dengan json.Unmarshal dan cetak.
Solusi tersedia setelah 3 upaya
Apakah bidang `string nama` (huruf kecil) dari suatu struct disertakan oleh json.Marshal?
type U struct {
name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))