Sorunun geçmişi:
Defer, Swift'e (Go, C#'taki benzerlerinden ilham alınarak) hata oluştuğunda, işlevden çıkıldığında veya işlevin farklı noktalarından değer dönerken kaynakların garantili bir şekilde temizlenmesi için eklenmiştir.
Sorun:
Erken serbest bırakma, unutulan kaynak temizlemeleri (örneğin, dosyaların kapatılması, günlüğe kaydetme, işlem geri alma). Bazen yürütme sırası ile karıştırılır ve defer'in tanımlandığı anda çalıştırıldığına inanılır.
Çözüm:
Defer, mevcut alanın (scope) sonuna kadar kodun çalıştırılmasını erteleyen özel bir bloktur, genellikle işlevde. Tüm defer, yerleştirme sırasına ters (LIFO) olarak çalıştırılır. Bu, kaynakların temizlenmesi, hafızanın serbest bırakılması veya işlemlerin geri alınması üzerinde merkezi bir kontrol sağlamaktadır.
Kod örneği:
func processFile() { let file = File("/tmp/data.txt") file.open() defer { file.close() print("Dosya kapatıldı") } // Dosya ile çalışma print("Veri okunuyor…") }
Ana özellikler:
Defer içindeki kod, uygulama çökmeden önce işlevden çıkarken çalıştırılır mı?
Hayır, defer kodu sadece görünürlük alanından (scope) düzgün bir şekilde çıkıldığında çalıştırılır. Uygulama beklenmedik bir şekilde kapanırsa (örneğin, fatal error), defer çalıştırılmaz.
Defer içinde return kullanılabilir mi?
Hayır, kullanılmaz. Defer bloğu değer döndürme veya alanı sonlandırmayı kabul etmez, sadece talimatlar.
Defer, defer'den önce tanımlanan değişkenlerin değiştirilmesinde kullanılabilir mi?
Evet, defer, yürütme anında mevcut yığın değerlerini yakalar. Defer'den önce tanımlanan değerler değiştirilebilir ve alanın çıkışında korunur.
Kod örneği:
func example() -> Int { var result = 0 defer { result = 42 } return result // defer çalışacak, sonuç — 42 }
Dosya açılır, ancak işlevin en altında açıkça kapatılmadığı için, hatalar veya işlevden erken çıkış durumlarında dosya açık kalır.
Artılar:
Eksiler:
Dosyayı açar açmaz kapatmak için defer kullanımı. Bir istisna meydana gelse bile veya işlevden dönüldüğünde dosya garantili olarak kapanacaktır.
Artılar:
Eksiler: