ProgramlamaGo geliştirici

Go'da defer'in nasıl çalıştığını ve çağrı sıralamasının ne zaman beklenmedik hale gelebileceğini açıklayın. Pratikte karşılaşılan bazı tuzaklar nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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 } }

Yanıltıcı soru.

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.

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri.


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.