الانتقال إلى المحتوى الرئيسي
الوحدة 8 · الدرس 5 من 540/50 في الدورة~14 min
دروس الوحدة (5/5)

"الترميز/json".

encoding/json هي الحزمة الأساسية لإجراء تسلسل بنيات Go إلى JSON والعودة. إن معرفة اصطلاحاته ومزالقه توفر عليك ساعات من تصحيح الأخطاء في واجهات برمجة التطبيقات وملفات التكوين.

المارشال وأونمارشال

الوظيفتين الرئيسيتين:

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)

بالنسبة للمخرجات ذات المسافة البادئة (يمكن قراءتها بواسطة الإنسان)، استخدم json.MarshalIndent(v, "", " ").

الحقول المصدرة فقط

json.Marshal يقوم بتسلسل الحقول المصدرة فقط (أحرف كبيرة). يتم تجاهل الحقول الخاصة بصمت:

Go
type U struct {
    Name string // exported → serialized
    age  int    // private → ignored
}

علامات الهيكل: التحكم في الاسم والخيارات

تتحكم العلامات json:"..." في الاسم والإغفال والأنواع في الإخراج:

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
}

الخيارات الأكثر استخدامًا:

  • ,omitempty — يحذف الحقل إذا كانت القيمة صفر (0، ""، صفر، شريحة/خريطة فارغة).
  • ,- — لا يتم إجراء تسلسل أو إلغاء تسلسل مطلقًا.
  • ,string — يلتف حول الأرقام/القيم المنطقية كسلاسل (مفيدة لمعرفات JS).

وحدة فك التشفير/التشفير للتيارات

عند العمل مع io.Reader/io.Writer (نص HTTP، الملفات الضخمة) استخدم Decoder وEncoder بدلاً من تحميل كل شيء في الذاكرة:

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 أيضًا dec.Token() للتحليل المتدفق قطعة تلو الأخرى وdec.DisallowUnknownFields() لرفض JSON باستخدام مفاتيح غير متوقعة (مفيد للتحقق من صحة الإدخال).

الخرائط العامة و any

إذا كنت لا تعرف المخطط، فقم بإلغاء التسلسل إلى map[string]any:

Go
var v map[string]any
_ = json.Unmarshal(data, &v)
fmt.Println(v["name"])

ستحتوي القيم على أنواع ديناميكية (string، float64 للأرقام، []any، map[string]any، bool، nil).

الأخطاء الشائعة

  • نسيان &: json.Unmarshal(data, v) لا يملأ أي شيء؛ أنت بحاجة إلى &v.
  • فك تشفير البنيات التي تحتوي على حقول صفرية: لتجنب الذعر، تحقق من err قبل قراءة الحقول.
  • الأنواع غير المتوافقة: يؤدي إلغاء تسلسل رقم إلى سلسلة أو العكس إلى إرجاع *json.UnmarshalTypeError.

تمارين

تمرين#go.m8.l5.e1
المحاولات: 0جارٍ التحميل…

قم بإجراء تسلسل للهيكل u إلى JSON باستخدام json.Marshal وطباعة النتيجة كسلسلة.

جارٍ تحميل المحرر…

الحل متاح بعد 3 من المحاولات

تمرين#go.m8.l5.e2
المحاولات: 0جارٍ التحميل…

قم بإلغاء تسلسل `{"Name": "Ada"}` في البنية U باستخدام json.Unmarshal ثم قم بطباعته.

جارٍ تحميل المحرر…

الحل متاح بعد 3 من المحاولات

Quiz#go.m8.l5.e3
جاهز

هل تم تضمين الحقل "سلسلة الاسم" (أحرف صغيرة) للبنية بواسطة json.Marshal؟

Go
type U struct {
  name string
}
b, _ := json.Marshal(U{name: "Ada"})
fmt.Println(string(b))
خيارات الإجابة