هذه الكلمات الثلاث تتعامل مع التنفيذ المؤجل والحالات الاستثنائية. defer يجدول استدعاء دالة للتنفيذ لاحقاً، panic يؤدي إلى انهيار وقت التشغيل (للحالات الاستثنائية حقاً)، و recover يمكنه اكتشاف panic لمنع انهيار البرنامج.
هذه الكلمات الثلاث تتعامل مع التنفيذ المؤجل والحالات الاستثنائية. defer يجدول استدعاء دالة للتنفيذ لاحقاً، panic يؤدي إلى انهيار وقت التشغيل (للحالات الاستثنائية حقاً)، و recover يمكنه اكتشاف panic لمنع انهيار البرنامج.
func readFile() error {
f, err := os.Open("file.txt")
if err != nil { return err }
defer f.Close() // GUARANTEED to run when readFile returns (any path)
// ... use f, with multiple return points ...
return nil // f.Close() runs here automatically
}
defer يجدول استدعاء دالة للتنفيذ عند عودة الدالة المحيطة — بغض النظر عن كيفية العودة (عودة عادية، خطأ، أو panic). إنها الطريقة الحقيقية لضمان التنظيف: إغلاق الملفات، فتح الأقفال، إغلاق الاتصالات — توضع مباشرة بجانب الاستحواذ حتى لا تنساها.
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
// prints: 3, 2, 1 — last deferred, first executed (stack order)
func mustPositive(n int) {
if n < 0 {
panic("negative not allowed") // stops normal execution, unwinds the stack
}
}
// panic runs deferred functions as it unwinds, then crashes the program (with a stack trace)
panic يوقف التدفق الطبيعي ويفك مكدس الاستدعاءات (تشغيل الدوال المؤجلة في الطريق)، وفي النهاية ينهي البرنامج. إنه لـ أخطاء المبرمج / الحالات غير القابلة للاسترجاع (تجاوز الحدود، إلغاء المراجع الفارغة، الحالات المستحيلة) — لا للأخطاء العادية (تلك تستخدم قيم error المرجعة).
func safeProcess() {
defer func() {
if r := recover(); r != nil { // recover() returns the panic value
fmt.Println("recovered from:", r) // handle it; program continues
}
}()
panic("something broke") // this panic is caught by the recover above
}
// safeProcess returns normally instead of crashing
recover يستعيد التحكم في goroutine المنهار — لكن يعمل فقط داخل دالة مؤجلة. يُستخدم بشكل نادر، على سبيل المثال لمنع معالج طلب واحد من إسقاط الخادم بأكمله.
Normal/expected failures (file missing, bad input, validation) → return an error value
panic/recover → reserve for TRULY exceptional cases (bugs, unrecoverable states)
and boundaries (e.g. a server recovering so one bad request doesn't kill the process)
defer ميزة Go أساسية وحقيقية لـ التنظيف المضمون — توضع إطلاق الموارد مباشرة بجانب الاستحواذ وضمان تشغيلها على كل مسار إرجاع (بما في ذلك panics)، مما يمنع تسرب الملفات والأقفال والاتصالات بشكل أكثر موثوقية من التنظيف اليدوي.
فهم ترتيب LIFO الخاص به مهم أيضاً. panic/recover يوفران آلية تشبه الاستثناءات، لكن المبدأ الحاسم هو أن Go تحفظهما للحالات الاستثنائية الحقيقية والغير قابلة للاسترجاع — يجب أن تُرجع الأخطاء العادية دائماً كقيم وتُفحص.
إساءة استخدام panic/recover كمعالجة استثناءات عامة أمر غير حقيقي وخطأ شائع بين المطورين القادمين من لغات قائمة على الاستثناءات.
معرفة متى تستخدم defer (دائماً، للتنظيف)، و error returns (الفشل العادي)، و panic/recover (نادراً، استثنائي، أو عند الحدود) أمر أساسي لكتابة Go صحيح وحقيقي وموضوع مقابلة متكرر.