خطأ Scopelint: استخدام متغير على نطاق النطاق
في وظيفة اختبار TestGetUID، يواجه الكود خطأ تم الإبلاغ عنه بواسطةscopelint، والذي يحذر من باستخدام المتغير x من نطاق النطاق ضمن القيم الحرفية للوظيفة.
خذ بعين الاعتبار الكود التالي الأسطر:
for _, x := range tests {
t.Run(x.description, func(t *testing.T) {
client := fake.NewSimpleClientset(x.objs...)
actual := getUID(client, x.namespace)
assert.Equal(t, x.expected, actual)
})
}
الخطأ يتعلق بهذه الأسطر لأن x هو متغير الحلقة داخل حلقة النطاق التي تتكرر على شريحة الاختبارات. يكتشف Scopelint أن x يتم استخدامه في القيم الحرفية للدالة التي تم تمريرها إلى t.Run()، مما قد يؤدي إلى مشكلات محتملة إذا تم استدعاء القيم الحرفية للدالة بعد عودة t.Run().
السبب و أفضل الممارسات
تنشأ المشكلة لأن المترجم لا يمكنه ضمان عدم استدعاء القيم الحرفية للدالة التي تم إنشاؤها وتمريرها إلى t.Run() بعد t.Run() مخارج. إذا تم استدعاء القيم الحرفية للدالة بعد إرجاع t.Run()، فإنها ستشير إلى المتغير x، والذي ربما تم استبداله بالقيمة من التكرار اللاحق للحلقة.
يرفع Go vet هذا التحذير إلى منع مثل هذا السلوك غير المقصود، والذي يمكن أن يؤدي إلى أخطاء أو حتى سباقات بيانات إذا تم تنفيذ القيم الحرفية للوظيفة بشكل متزامن في goroutines مختلفة.
أفضل الممارسات الموصى بها في مثل هذه الحالات هي إما المرور قيمة لمتغير الحلقة إلى الدالة الحرفية كوسيطة أو إنشاء نسخة من متغير الحلقة والإشارة إلى النسخة داخل الدالة الحرفية. نظرًا لأنه لا يمكن تغيير توقيع الدالة الحرفية، فإن الحل الموصى به هو إنشاء نسخة، على سبيل المثال:
x2 := x
بعد الإعلان عن هذه النسخة، معرف x داخل ستشير الدالة الحرفية إلى النسخة المحلية، وليس إلى متغير الحلقة. على الرغم من أن تعيين نفس الاسم للنسخة قد يبدو مربكًا، إلا أنه يشير بوضوح إلى نية استخدام نسخة.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3