Modül dersleri (5/5)
'kodlama/json'
encoding/json Go yapılarını JSON'a ve JSON'a serileştirmek için kullanılan standart pakettir. Kurallarını ve tuzaklarını bilmek, sizi API'lerde ve yapılandırma dosyalarında saatlerce hata ayıklamaktan kurtarır.
Mareşal ve Mareşal
İki ana işlev:
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)Girintili çıktı için (insan tarafından okunabilir) json.MarshalIndent(v, "", " ") kullanın.
Yalnızca dışa aktarılan alanlar
json.Marshal yalnızca dışa aktarılan alanları (Büyük harf) serileştirir. Özel alanlar sessizce göz ardı edilir:
type U struct {
Name string // exported → serialized
age int // private → ignored
}Yapı etiketleri: adı ve seçenekleri kontrol etme
json:"..." etiketleri çıktıdaki adı, ihmali ve türleri kontrol eder:
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
}En çok kullanılan seçenekler:
,omitempty— sıfır değer (0, "", sıfır, boş dilim/harita) ise alanı atlar.,-— hiçbir zaman seri hale getirilmedi/seri durumdan çıkarılmadı.,string— sayıları/boolları dize olarak sarar (JS kimlikleri için kullanışlıdır).
Akışlar için Kod Çözücü/Kodlayıcı
io.Reader/io.Writer (HTTP gövdesi, büyük dosyalar) ile çalışırken, belleğe her şeyi yüklemek yerine Decoder ve Encoder kullanın:
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 ayrıca parça parça ayrıştırma akışı için dec.Token()'yi ve beklenmedik anahtarlarla JSON'u reddetmek için dec.DisallowUnknownFields()'yi de destekler (giriş doğrulama için kullanışlıdır).
Genel haritalar ve any
Şemayı bilmiyorsanız map[string]any şeklinde seri durumdan çıkarın:
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])Değerlerin dinamik türleri olacaktır (sayılar için string, float64, []any, map[string]any, bool, nil).
Yaygın hatalar
&unutmak:json.Unmarshal(data, v)hiçbir şeyi doldurmaz;&v'ya ihtiyacınız var.- Sıfır alanlarla yapıların kodunun çözülmesi: paniği önlemek için alanları okumadan ÖNCE
erröğesini kontrol edin. - Uyumsuz türler: Bir sayının seri durumdan bir dizeye dönüştürülmesi veya tam tersi,
*json.UnmarshalTypeErrordeğerini döndürür.
Egzersizler
u yapısını json.Marshal ile JSON'a serileştirin ve sonucu bir dize olarak yazdırın.
3 denemeden sonra çözüm mevcut
json.Unmarshal ile U yapısında `{"Name":"Ada"}` seri durumunu kaldırın ve yazdırın.
3 denemeden sonra çözüm mevcut
Bir yapının "ad dizesi" (küçük harf) alanı json.Marshal tarafından dahil edilmiş mi?
type U struct {
name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))