"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية تخصيص JSON Unmarshaling مع الانعكاس في Go؟

كيفية تخصيص JSON Unmarshaling مع الانعكاس في Go؟

تم النشر بتاريخ 2024-11-16
تصفح:252

How to Customize JSON Unmarshaling with Reflection in Go?

تخصيص تفكيك JSON مع الانعكاس

في Go، يعد إلغاء تنظيم JSON في بنية عملية مباشرة. ومع ذلك، عند التعامل مع الحقول التي تحتوي على علامات مخصصة، مثل json:"some_field"، قد لا تكون آلية إلغاء التنظيم القياسية كافية.

أحد الأساليب للتعامل مع هذا السيناريو هو استخدام الانعكاس. من خلال فحص حقول البنية باستخدام الانعكاس، يمكننا التحقق مما إذا كان الحقل يحتوي على علامة محددة وإذا كان الأمر كذلك، فإننا نتعامل مع إلغاء تنظيمه وفقًا لذلك.

في هذه الحالة بالذات، نريد التأكد من أن الحقل الذي يحتوي على علامة json هو غير منظم في حقل سلسلة كما هو. يتيح لنا ذلك التعامل مع كائنات أو مصفوفات JSON ضمن بنية Go.

مثال على السيناريو

ضع في اعتبارك بيانات JSON التالية وبنية Go:

{
  "I": 3,
  "S": {
    "phone": {
      "sales": "2223334444"
    }
  }
}
type A struct {
    I int64
    S string `sql:"type:json"`
}

هدفنا هو إلغاء تنظيم الحقل "S" كسلسلة، مع الحفاظ على بنية JSON المتداخلة.

الحل باستخدام الانعكاس

ما يلي يوضح الكود كيفية تحقيق ذلك باستخدام الانعكاس:

func main() {
    a := A{}

    // Unmarshal the JSON data into a byte slice
    var data []byte

    // Iterate over the fields of the struct
    typ := reflect.TypeOf(a)
    val := reflect.ValueOf(a)
    for i := 0; i 

في هذا الأسلوب، نقوم يدويًا بفحص كل حقل في البنية باستخدام الانعكاس لتحديد ما إذا كان يحتوي على علامة "json". إذا كان الأمر كذلك، فإننا نقوم بإلغاء تنظيم بيانات JSON في الحقل كسلسلة.

الحل البديل باستخدام Custom Marshaler وUnmarshaler

هناك خيار آخر وهو تنفيذ نوع مخصص، مثل RawString، الذي يقوم بتنفيذ واجهات json.Marshaler وjson.Unmarshaler. وهذا يسمح بمزيد من المرونة والتحكم في عملية إلغاء التنظيم.

يتم توضيح هذا الأسلوب في التعليمة البرمجية التالية:

// RawString is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawString string

// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawString) MarshalJSON() ([]byte, error) {
    return []byte(*m), nil
}

// UnmarshalJSON sets *m to a copy of data.
func (m *RawString) UnmarshalJSON(data []byte) error {
    if m == nil {
        return errors.New("RawString: UnmarshalJSON on nil pointer")
    }
    *m  = RawString(data)
    return nil
}

const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`

type A struct {
    I int64
    S RawString `sql:"type:json"`
}

func main() {
    a := A{}
    err := json.Unmarshal([]byte(data), &a)
    if err != nil {
        log.Fatal("Unmarshal failed", err)
    }
    fmt.Println("Done", a)
}

من خلال تنفيذ النوع الخاص بنا، يمكننا تخصيص عملية إلغاء التنظيم وتجنب الحاجة إلى التفكير، مما يؤدي إلى حل أنظف وأكثر كفاءة.

أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3