Panic, Defer ve Recover
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 57 / 107.
Go, hataları döndürmeyi vurgulasa da bazı durumlar gerçekten kurtarılamaz. Bu durumlar için Go, istisnai koşulları ele almaya yönelik bir mekanizma olarak panic, defer ve recover yapılarını sunar.
panic normal yürütmeyi hemen durdurur. Kullanıcı girdisinin geçersiz olması gibi beklenen hatalar için değil, sınırların dışındaki bir dizine erişmek gibi programlama hataları için ayrılmıştır:
func MustGetConfig(key string) string {
value, exists := config[key]
if !exists {
panic("missing required config: " + key)
}
return value
}defer, çevreleyen işlev normal olarak veya bir panic nedeniyle döndüğünde çalıştırılmak üzere bir işlevi zamanlar. Ertelenen çağrılar ters sırada (son giren, ilk çıkar) yürütülür:
func ProcessFile() {
fmt.Println("Opening file")
defer fmt.Println("Closing file")
fmt.Println("Processing...")
// Çıktı: Opening file, Processing..., Closing file
}recover bir panic'i yakalar ve normal yürütmeye geri döner. Yalnızca ertelenmiş bir işlevin içinde çalışır:
func SafeOperation() (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("recovered from panic: %v", r)
}
}()
riskyOperation()
return nil
}Bu desen, bir panic'i normal bir hataya dönüştürerek programınızın devam etmesini sağlar. Bunu ölçülü kullanın: beklenen başarısızlık durumları için hata döndürmeyi tercih edin ve panic/recover kullanımını bozulmuş durum veya kurtarılamaz koşullar gibi gerçekten istisnai durumlarla sınırlayın.
Görev
Kolaypanic, defer ve recover kullanarak olağandışı durumları düzgün bir şekilde ele almayı gösteren güvenli bir bölme hesaplayıcısı oluşturalım. Hesaplayıcınız riskli işlemleri deneyecek ve panic durumlarını normal şekilde ele alınabilecek normal hatalara dönüştürecektir.
Kodunuzu iki dosyaya ayıracaksınız:
calculator.go: Panic kurtarma özelliğiyle bölme mantığını oluşturun.İki tamsayı alan ve bölen sıfırsa
Dividemesajıyla panic oluşturan bir"division by zero"fonksiyonu uygulayın. Aksi takdirde bölme işleminin tamsayı sonucunu döndürmelidir.İki tamsayı alan ve hem bir tamsayı sonucu hem de bir hata döndüren bir
SafeDividefonksiyonu uygulayın. Bu fonksiyon şunları yapmalıdır:- Herhangi bir panic durumundan kurtulmak için anonim bir fonksiyonla birlikte
deferkullanın - Bir panic kurtarılırsa, onu
"calculation error: [panic message]"biçiminde bir hataya dönüştürün - Dahili olarak
Dividefonksiyonunu çağırın - Başarılı olursa sonucu ve
nildeğerini, bir panic kurtarılmışsa sıfırı ve hatayı döndürün
- Herhangi bir panic durumundan kurtulmak için anonim bir fonksiyonla birlikte
main.go: Girdiden iki tamsayı okuyun ve hesaplamayı güvenli bir şekilde gerçekleştirmek içinSafeDividekullanın. Ayrıca doğru sırada temizlik mesajları yazdırarakdeferkullanımını gösterin.main fonksiyonunuz şunları yapmalıdır:
- Başlangıçta
Starting calculationyazdırın deferyazdırmayı planlamak içinCleanup completekullanındeferyazdırmayı planlamak için başka birReleasing resourceskullanın- Girdi değerleriyle
SafeDividefonksiyonunu çağırın - Sonuca göre
Result: [value]veyaError: [error message]yazdırın
- Başlangıçta
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: İlk tamsayı (bölünen)
- 2. satır: İkinci tamsayı (bölen)
Ertelenen çağrıların ters sırada (son giren, ilk çıkar) yürütüldüğünü unutmayın; bu nedenle temizlik mesajlarınız, ertelendikleri sıranın tersi olan sırada görünmelidir.
Örneğin, 20 ve 4 verildiğinde çıktınız şu şekilde olmalıdır:
Starting calculation
Result: 5
Releasing resources
Cleanup completeVe 10 ile 0 verildiğinde çıktınız şu şekilde olmalıdır:
Starting calculation
Error: calculation error: division by zero
Releasing resources
Cleanup completeKendin dene
package main
import (
"fmt"
)
func main() {
// Girdiyi oku
var dividend, divisor int
fmt.Scanln(÷nd)
fmt.Scanln(&divisor)
// Başlangıç mesajını yazdır
fmt.Println("Starting calculation")
// TODO: Use defer to schedule "Cleanup complete" message
// TODO: Use defer to schedule "Releasing resources" message
// Unutma: ertelenmiş çağrılar LIFO sırasıyla çalışır (son giren, ilk çıkar)
// TODO: SafeDivide'ı girdi değerleriyle çağır
// TODO: Ya "Result: [value]" ya da "Error: [error message]" yazdır
// bir hata döndürülüp döndürülmediğine göre
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker PoolKendi başına pratik yap: Online Go derleyicisi