"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية التغلب على SetCan() الذي يُرجع الخطأ دائمًا عند تعيين قيم حقل البنية باستخدام الانعكاس؟

كيفية التغلب على SetCan() الذي يُرجع الخطأ دائمًا عند تعيين قيم حقل البنية باستخدام الانعكاس؟

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

How to Overcome SetCan() Always Returning False When Setting Struct Field Values Using Reflection?

استكشاف الانعكاس باستخدام SetString للهياكل

يوفر الانعكاس أدوات قوية لمعالجة هياكل Go ديناميكيًا. في هذا المثال، نواجه مشكلة شائعة عند محاولة تعيين قيمة حقل البنية باستخدام الانعكاس: تقوم CanSet() دائمًا بإرجاع خطأ. يمنع هذا العائق إجراء تعديلات على الحقول، مما يتركنا في مأزق.

تحديد المزالق

يسلط مقتطف الكود المقدم الضوء على خطأين أساسيين:

  1. ]تمرير قيمة بدلاً من المؤشر: لا يمكن تعديل الهياكل حسب القيمة من خلال الانعكاس. بدلاً من ذلك، يجب علينا تمرير مؤشر إلى البنية، مما يضمن تطبيق أي تغييرات على الكائن الفعلي.
  2. استهداف العناصر غير صحيح: تعمل التعليمات البرمجية في البداية على بنية ProductionInfo بأكملها بدلاً من إدخال محدد يجب تغيير قيمة Field1 الخاصة به. لتصحيح هذا، نحن بحاجة إلى التركيز على عنصر الإدخال المطلوب.

حل المشكلات

بعد معالجة هذه المخاطر، يمكننا تحسين الكود الخاص بنا:

func SetField(source interface{}, fieldName string, fieldValue string) {
    v := reflect.ValueOf(source).Elem() // Obtain the value of the pointed object
    fmt.Println(v.FieldByName(fieldName).CanSet())
    if v.FieldByName(fieldName).CanSet() {
        v.FieldByName(fieldName).SetString(fieldValue)
    }
}
في وظيفة SetField() المعدلة، نقوم بما يلي:

    استخدم Elem() للانتقال إلى قيمة الكائن المدبب، مما يضمن أننا نعمل على البنية الفعلية.
  1. ]
  2. استخدم FieldByName() للوصول إلى الحقل المحدد الذي نريد تعديله.

أدخل الكود الإجراء

بفضل هذه التعديلات، ينجح الكود الآن في تحديث قيمة Field1:

func main() {
    source := ProductionInfo{}
    source.StructA = append(source.StructA, Entry{Field1: "A", Field2: 2})

    fmt.Println("Before: ", source.StructA[0])
    SetField(&source.StructA[0], "Field1", "NEW_VALUE")
    fmt.Println("After: ", source.StructA[0])
}
الإخراج:

قبل: {A 2} حقيقي بعد: {NEW_VALUE 2}
Before:  {A 2}
true
After:  {NEW_VALUE 2}
تعرض النتيجة التعديل الناجح للحقل 1 داخل بنية الإدخال.

بيان الافراج يتم استنساخ هذه المقالة في: 1729662680 إذا كان هناك أي انتهاك ، فيرجى الاتصال بـ [email protected] لحذفه.
أحدث البرنامج التعليمي أكثر>

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

Copyright© 2022 湘ICP备2022001581号-3