Go / دليل حلول تحريري
تشخيص مؤشرات nil وواجهاتها ذات النوع
حدد القيمة nil واستعد عقد إنشائها وأعد خطأ nil حقيقيا عند النجاح.
قاعدة معرفة للقراءة فقط · بلا تعليقات عامة
تعرّف على الأعراض
يبلغ برنامج محلي "invalid memory address or nil pointer dereference"، أو يدخل المستدعي فرع err != nil رغم أن مؤشر الخطأ الملموس nil. قد يضلل العرض المطبوع؛ فتبدو القيمة nil بينما واجهتها غير nil. المساران مترابطان لكن تشخيصهما مختلف.
افهم الأسباب المحتملة
- قد يكون المؤشر غير مهيأ أو معادا كغائب دون فحص أو داخل قيمة أخرى. تساوي الواجهة nil فقط عند غياب نوعها وقيمتها الديناميكيين. يمنح تحويل *Problem صفري إلى error نوعا ديناميكيا. وقد تصح طريقة على مؤشر nil فقط إذا تجنب جسمها فك الإشارة غير الصالح عمدا.
1. تحديد فك الإشارة الفعلي
احفظ تتبع المكدس وحدد أول إطار تطبيق ذي صلة في إعادة محلية اصطناعية. حدد المستقبل أو الحقل أو المؤشر وتتبع إنشاءه وخطأه المعاد. لا تضف فحص nil عشوائيا لإخفاء الانهيار؛ ينبغي غالبا رفض اعتماد مطلوب غائب أثناء التهيئة لا تخطي عمل أساسي بصمت.
2. فصل nil المؤشر من nil الواجهة
افحص النوع المعلن والديناميكي عند حد الواجهة. يفيد عرض مقارنة آمن أكثر من تنفيذ فك nil عمدا. يوضح المثال الكامل واجهة تحمل nil ذا نوع وعودة نجاح مصححة. لا تفك Error المستقبل، ولذلك لا ينسب العرض خرج هلع مختلقا لشيفرة غير صالحة.
package main
import "fmt"
type Problem struct{}
func (*Problem) Error() string { return "problem" }
func validate(valid bool) error {
if !valid {
return &Problem{}
}
return nil
}
func main() {
var pointer *Problem
var wrapped error = pointer
fmt.Println("pointer nil", pointer == nil, "interface nil", wrapped == nil)
fmt.Println("success nil", validate(true) == nil)
}
pointer nil true interface nil false
success nil true
يقدم المؤشر المحول نوعا ديناميكيا؛ ولا تقدم عودة nil الصريحة نوعا ولا قيمة.
3. إصلاح الإنشاء ومعالجة الغياب
تحقق من إنشاء الكائن المطلوب ومرر خطأه قبل تخزينه أو استخدامه. وللاختياري وثق هل تعني nil الغياب وليطبق المستدعي أو الطريقة ذلك صراحة. أعد nil مباشرة من دالة خطأ عند النجاح. لا تعد مؤشرا صفريا ذا نوع لمجرد صحة مقارنته الملموسة.
4. فحص النوع الديناميكي دون هلع آخر
إذا حملت الواجهة بدائل موثقة فاستخدم comma-ok أو type switch. قد يهلع التأكيد المباشر لتنفيذ مختلف صالح. لا تبدأ بمساعد انعكاس عام لفحص nil؛ فقد يخفي واجهة غامضة ولا يقرر صلاحية الغياب للمجال. فضل عقد نتيجة دقيقا أو نوعا اختياريا ملموسا.
5. اختبار حد الواجهة المعلن
اختبر إسناد نتائج النجاح والفشل لنوع الواجهة الفعلي. اشترط err == nil عند النجاح وفئة موثقة عند الفشل. إذا دُعم مستقبل nil فاختبر طريقته، وإلا ارفضه قبل الاستدعاء. أبق الرسائل للبشر واستخدم errors.Is أو errors.As للقرارات الموثقة.
تحقق من نجاح الإصلاح
يجب أن يطبع المثال pointer nil true interface nil false ثم success nil true. أعد السيناريو الأصلي المصغر بعد إصلاح الإنشاء أو الإرجاع. افحص النتيجة وسياسة الغياب لا البقاء دون هلع فقط. أضف اختبارات للاعتماد المطلوب الغائب والغياب الاختياري المدعوم وnil ذي نوع يعبر الواجهة.
امنع تكرار المشكلة
- اجعل فشل الإنشاء صريحا وأعد أخطاء nil حقيقية عند النجاح ووثق دعم المستقبل الصفري. فضل واجهات ضيقة واختبر عبرها. راجع التحويل للواجهة عندما يصبح النجاح خطأ غير nil، ولا تستنتج المساواة من التنسيق.