Ana içeriğe geç
Modül 8 · Ders 5 ders 5Kurstaki 40/50~14 min
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:

Go
data, err := json.Marshal(v)      // Go → []byte JSON
err = json.Unmarshal(data, &v)    // JSON → Go (pass a pointer!)
Go
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:

Go
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:

Go
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:

Go
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:

Go
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.UnmarshalTypeError değerini döndürür.

Egzersizler

Egzersiz#go.m8.l5.e1
Denemeler: 0Yükleniyor…

u yapısını json.Marshal ile JSON'a serileştirin ve sonucu bir dize olarak yazdırın.

Düzenleyici yükleniyor…

3 denemeden sonra çözüm mevcut

Egzersiz#go.m8.l5.e2
Denemeler: 0Yükleniyor…

json.Unmarshal ile U yapısında `{"Name":"Ada"}` seri durumunu kaldırın ve yazdırın.

Düzenleyici yükleniyor…

3 denemeden sonra çözüm mevcut

Quiz#go.m8.l5.e3
Hazır

Bir yapının "ad dizesi" (küçük harf) alanı json.Marshal tarafından dahil edilmiş mi?

Go
type U struct {
  name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))
Cevap seçenekleri