Go'daki defer anahtar kelimesi, belirtilen fonksiyonların, çevresindeki fonksiyondan çıkmadan önce gerçekleştirilmesini erteleyerek çalışır — fonksiyonlar yığında toplanır ve ters sırayla (LIFO) çalıştırılır. Bu genellikle kaynakların (dosyalar, mutex, bağlantılar) serbest bırakılması için kullanılır.
Özellik — defer'e geçirilen tüm fonksiyon argümanları, icra anı değil, ilan anında hemen hesaplanır.
func test() { for i := 0; i < 3; i++ { defer fmt.Println(i) // Yazdırır: 2, 1, 0 } }
Aşağıdaki kod ne gösterecek?
func main() { for i := 0; i < 3; i++ { defer fmt.Println(i) } }
Cevap:
Bu, şunu gösterecektir:
2
1
0
Çünkü her döngüde i argümanı hemen hesaplanır (defer anında), ve tüm değerler defer yığında saklanır.
Hikaye
Bir dosya hizmetinde, defer'in yalnızca normal koşullar altında fonksiyondan çıkarken çağrıldığını hesaba katmayı unuttular. Defer çağrısından önce program aniden sona erdiğinde sızıntılar meydana geldi.
Hikaye
Bir veri akışında unutma — döngüde bağlantıları kapatmak için defer kullanıldı, ancak aslında yalnızca tüm fonksiyon tamamlandıktan sonra kapandılar, her yinelemeden sonra değil. Bu, kaynakların tükenmesine yol açtı.
Hikaye
Bir günlük kaydedicisinde, defer, anonim bir fonksiyonla kullanıldı ve argümanın çağrı anında hesaplanacağı düşünüldü. Bu nedenle, sonunda günlüğü, değerlerin daha önce yakalanmış olması nedeniyle, güncel olmayan bilgiler içeriyordu.