العمل مع JSON في Go: تحليل البيانات وتسلسلها

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة عن العمل مع JSON في Go

JSON (JavaScript Object Notation) هو تنسيق خفيف لتبادل البيانات يُستخدم على نطاق واسع في تطبيقات الويب وواجهات برمجة التطبيقات (APIs) والخدمات المصغرة. توفر لغة Go (Golang) مكتبة مدمجة قوية encoding/json تجعل من السهل تحليل البيانات (إلغاء التسلسل) وتسلسلها. في هذه المقالة، سنفحص بالتفصيل كيفية العمل مع JSON في Go، مع تغطية الوظائف الرئيسية والهياكل وأفضل الممارسات.



أساسيات التسلسل وإلغاء التسلسل

التسلسل (Serialization) هو عملية تحويل بنية بيانات Go (مثل هيكل (struct) أو شريحة (slice)) إلى سلسلة JSON. إلغاء التسلسل (Deserialization) هو العملية العكسية — تحويل JSON إلى بنية Go.



التسلسل (Marshal)

للتسلسل، تُستخدم الدالة json.Marshal(). تأخذ قيمة Go وتُرجع شريحة بايت ([]byte) تحتوي على تمثيل JSON.

package main

import ( "encoding/json" "fmt")

type User struct { Name string `json:"name"` Age int `json:"age"` Email string `json:"email,omitempty"`}

func main() { user := User{Name: "Alexey", Age: 30, Email: "alex@example.com"} jsonData, err := json.Marshal(user) if err != nil { fmt.Println("Serialization error:", err) return } fmt.Println(string(jsonData)) // Output: {"name":"Alexey","age":30,"email":"alex@example.com"}

لاحظ الوسوم json:"field_name". تسمح لك بالتحكم في أسماء المفاتيح في JSON، بالإضافة إلى إضافة خيارات مثل omitempty (تخطي الحقل إذا كان فارغًا).



إلغاء التسلسل (Unmarshal)

لتحليل JSON إلى بنية Go، تُستخدم الدالة json.Unmarshal(). تأخذ شريحة بايت ومؤشرًا إلى الهيكل الذي يجب كتابة البيانات فيه.

func main() {    jsonString := `{"name":"Maria","age":25,"email":"maria@example.com"}`    var user User    err := json.Unmarshal([]byte(jsonString), &user)    if err != nil {        fmt.Println("Parsing error:", err)        return    }    fmt.Printf("Name: %s, Age: %d, Email: %s", user.Name, user.Age, user.Email)}

مهم: يجب أن يكون الهيكل محددًا مسبقًا، ويجب أن تتوافق حقوله مع مفاتيح JSON (مع مراعاة الوسوم).



العمل مع كائنات JSON غير محددة

أحيانًا يكون بنية JSON غير معروفة مسبقًا أو معقدة للغاية. في هذه الحالات، يمكنك استخدام map[string]interface{} أو interface{}.



استخدام map[string]interface{}
func main() {    jsonString := `{"name":"Ivan","age":35,"address":{"city":"Moscow","street":"Lenina"}}`    var result map[string]interface{}    err := json.Unmarshal([]byte(jsonString), &result)    if err != nil {        fmt.Println("Error:", err)        return    }    fmt.Println(result["name"]) // Ivan    fmt.Println(result["age"])  // 35 (type float64)    // For nested objects, type assertion is needed    address := result["address"].(map[string]interface{})    fmt.Println(address["city"]) // Moscow}

عيب هذا الأسلوب هو الحاجة إلى تأكيد النوع يدويًا (.(map[string]interface{}))، والذي قد يتسبب في حالة ذعر (panic) إذا لم تتطابق الأنواع.



استخدام json.RawMessage

إذا كنت بحاجة إلى تأجيل تحليل جزء من JSON، استخدم json.RawMessage. يتيح لك هذا تحليل الهيكل الرئيسي أولاً ثم معالجة البيانات المتداخلة بشكل منفصل.

type Response struct {    Status string          `json:"status"`    Data   json.RawMessage `json:"data"`}

func main() { jsonString := `{"status":"ok","data":{"user":"Peter","score":100}}` var resp Response json.Unmarshal([]byte(jsonString), &resp)

// Now Data can be parsed separately var userData map[string]interface{} json.Unm

المدونات

توصيات الكتب