Go با مثال: recover

Go این امکان را می‌دهد که با تابع داخلی recover از یک panic بازیابی (recover) کنیم. recover می‌تواند جلوی متوقف شدن برنامه توسط panic را بگیرد و اجازه دهد اجرا ادامه پیدا کند.

نمونه‌ای از جایی که این کار مفید است: یک سرور نمی‌خواهد اگر یکی از اتصال‌های کلاینت خطای بحرانی داشت، کرش کند. در عوض، سرور می‌خواهد آن اتصال را ببندد و به سرویس‌دهی به کلاینت‌های دیگر ادامه دهد. در واقع net/http در Go به‌طور پیش‌فرض همین کار را برای سرورهای HTTP انجام می‌دهد.

package main
import "fmt"

این تابع panic می‌کند.

func mayPanic() {
    panic("a problem")
}

recover باید داخل یک تابع defer‌شده صدا زده شود. وقتی تابع دربرگیرنده panic کند، defer فعال می‌شود و فراخوانی recover داخل آن panic را می‌گیرد.

func main() {

مقدار بازگشتی recover خطایی است که در فراخوانی panic ایجاد شده.

    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()
    mayPanic()

این کد اجرا نمی‌شود، چون mayPanic پنیک می‌کند. اجرای main در نقطهٔ panic متوقف می‌شود و در کلوژرِ defer‌شده ادامه پیدا می‌کند.

    fmt.Println("After mayPanic()")
}
$ go run recover.go
Recovered. Error:
 a problem

مثال بعدی: .