Soru Tarihçesi:
defer, panic ve recover operatörleri, Go'daki akış kontrolü için önemli mekanizmalardır. defer operatörü, fonksiyonları erteleyerek çalıştırmak için kullanılır, panic bir hata (acil durum) başlatır ve recover bir acil durumu yakalayıp çalışmaya devam etmeyi sağlar.
Sorun:
Bu araçların doğru kullanımı olmadan kaynakları düzgün bir şekilde finalizasyon yapmak ve hata toleransı sağlamak zordur. Fonksiyonun beklenmedik bir şekilde sona ermesi, serbest bırakılmamış kaynaklar ve hatalarla karşılaştığında uygulamanın kontrolsüz "çıkışı" yaygın sorunlardır.
Çözüm:
defer'in doğru uygulanması, hata durumunda bile kaynakların güvenli bir şekilde serbest bırakılmasını sağlar. panic kritik durumlar için bir acil durum sonlandırma mekanizmasıdır ve yalnızca gerçekten olağanüstü durumlar için kullanılmalıdır. recover, ertelenmiş bir fonksiyon içinde çalışmaya devam etme imkanı sağlar.
Kod örneği:
func riskyFunction() { defer func() { if r := recover(); r != nil { fmt.Println("riskyFunction içinde geri alındı:", r) } }() fmt.Println("Bir şeyler yapılıyor...") panic("kötü bir şey oldu!") } func main() { riskyFunction() fmt.Println("riskyFunction'dan sonra") }
Ana özellikler:
defer, fonksiyondan çıkmadan önce ters sırada her zaman çağrılır. Panic durumunda bile.recover yalnızca ertelenmiş fonksiyonlar içinde çalışır.panic, mevcut goroutine'in yürütülmesini durdurur; recover ile yakalanmazsa süreci sonlandırır.Neden recover, panic'in meydana geldiği aynı fonksiyon içinde defer dışında çalışmaz?
recover, panic'in meydana geldiği fonksiyon içinde çağrılan bir defer fonksiyonu tarafından çağrıldığında yalnızca sıfırdan farklı bir değer (yani paniklemeyi yakalar) döner. Recover doğrudan çağrılırsa, her zaman nil döner.
Kod örneği:
func f() { panic("başarısız!") r := recover() // çalışmıyor! }
Panic'dan sonra bir defer çağrılabilir mi ve çalışır mı?
Hayır. Panic'dan sonra tüm kayıtlı defer çağrıları çalıştırılır, ancak panic'dan sonra yeni defer'ler çağrılmaz çünkü fonksiyonun yürütülmesi "daralır".
Başka bir goroutine'de meydana gelen panic'den (recover) kurtulmak mümkün mü?
Hayır, recover yalnızca mevcut goroutine'deki panikler için çalışır. Başka bir goroutine panic yaparsa ve recover o goroutine'de çağrılmamışsa, uygulama sonlanır.
Projede tüm hatalar panic aracılığıyla fırlatıldı ve recovery işlemi yalnızca ana fonksiyonda gerçekleştirildi. Bu durum, kaynakların kapanmamasına, bazı verilerin kaybolmasına ve günlüklerin okunamaz hale gelmesine neden oldu.
Artılar:
Eksiler:
Her kritik bölümde kaynakları serbest bırakmak için defer kullanıldı, panic yalnızca gerçekten olağanüstü durumlar için kullanıldı ve recover nötr alanlarda kazaları izole etmek için kullanıldı. Ayrıca hataların tüm ayrıntıları günlüğe kaydedildi.
Artılar:
Eksiler: