Panic و Recover

panic، recover و defer — مکانیزم خطاهای بحرانی در Go.

panic چیست؟

panic خطای بحرانی است که برنامه را متوقف می‌کند — برای شرایط غیرقابل بازیابی:

func mustPositive(n int) int {
    if n < 0 {
        panic("عدد باید مثبت باشد!")
    }
    return n
}

defer — به تعویق انداختن

defer اجرای تابع را تا پایان تابع فعلی به تعویق می‌اندازد:

func main() {
    defer fmt.Println("۳. آخر (defer)")

    fmt.Println("۱. اول")
    fmt.Println("۲. دوم")
}
// خروجی: ۱. اول / ۲. دوم / ۳. آخر
رایج‌ترین کاربرد defer: بستن منابع (فایل، اتصال شبکه) — defer file.Close() تضمین می‌کند همیشه بسته شود!

چند defer — ترتیب LIFO

defer fmt.Println("اول")
defer fmt.Println("دوم")
defer fmt.Println("سوم")
// خروجی: سوم / دوم / اول (برعکس!)

recover — بازیابی از panic

recover فقط داخل defer کار می‌کند و panic را مهار می‌کند:

func safeDivide(a, b int) (result int, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("panic رخ داد: %v", r)
        }
    }()

    return a / b, nil   ← اگر b=0 باشد panic می‌شود
}

مثال کامل

func risky() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("بازیابی شد:", r)
        }
    }()

    panic("فاجعه!")
    fmt.Println("این خط هرگز اجرا نمی‌شود")
}

func main() {
    risky()
    fmt.Println("برنامه ادامه دارد!")   ← اجرا می‌شود
}

کی panic کنیم؟

وضعیتابزار
خطای قابل انتظار (فایل نبود، ورودی غلط)error
باگ برنامه‌نویس (impossible state)panic
مقدار nil در جایی که نبایدpanic
خطای کتابخانه‌ای بحرانیpanic
در کد کتابخانه‌ای (پکیج‌های قابل استفاده مجدد) panic نکنید — error برگردانید! panic فقط برای باگ‌های غیرقابل بازیابی برنامه اصلی است.

این مبحث بخشی از دوره آموزش کامل گو است.

ابزارهای مرتبط