ProgramlamaGo backend engineer

Go'da map ve slice ile çalışırken range mekanizmasının nasıl çalıştığını açıklayın. Döngü değişkenlerini kullanmanın incelikleri nelerdir ve hangi hatalarla karşılaşabilirsiniz?

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

Cevap

for ... range döngüsü, dilim (slice), harita (map), dizi veya dize (string) elemanları üzerinde kolayca geçiş yapmayı sağlar.

  • Slice için: Her döngüde indeks ve elemanın kopyasını döndürür.
  • Map için: Anahtar ve değerinin kopyasını döndürür.

Örnek:

s := []int{1, 2, 3} for i, v := range s { fmt.Println(i, v) } m := map[string]int{"a":1, "b":2} for k, v := range m { fmt.Println(k, v) }

Ana incelik: Değişkenler i, v, k vb. tüm döngülerde yeniden kullanılır! Bu, döngü içinde referansla geçerken veya range içinde goroutine çalıştırırken sık sık hata kaynağı olur.

Hileli Soru

Slice içinde bir goroutine başlatıp döngü değişkenini yakalarsak ne olur? Hatanın önüne nasıl geçebiliriz?

Cevap: Tipik bir hata meydana gelir: Goroutine içinde kullanılan döngü değişkenleri, döngü tamamlandıktan sonra son değeri alacaktır. Önlemek için yerel kopyalar oluşturmak gerekir:

nums := []int{1, 2, 3} for _, v := range nums { go func(val int) { fmt.Println(val) }(v) }

İncelikli Bilgilerden Dolayı Gerçek Hata Örnekleri


Hikaye

Bir projede, goroutine aracılığıyla bir slice'ı doldurmak için range kullanıldı, ancak döngü değişkenlerinin kopyaları oluşturulmadı. Tüm goroutineler, dizinin son değerini yazdırdı, bu da iş mantığını ciddi şekilde bozdu.


Hikaye

Map üzerinde range yaparken, değerlerin referansını yeni bir işaretçi dizisine kaydettik. Sonuç olarak, yeni dizinin tüm elemanları döngüde kullanılan aynı değişkene — değerinin kopyasına — referans oldu. Bu değişkenlerde döngü dışında güncelleme yapıldığında hata meydana geldi (panic: geçersiz bellek adresi veya beklenmeyen veriler).


Hikaye

Bir iç araçta string üzerinde range yaparak önemli alt dizeleri işleyen işleyicileri başlattım, ancak her bir döngü için baytlarda, Unicode karakterlerinde değil, kayma aldım. Sonuç: Unicode dizeleri için yanlış işleme, sembollerin yanlış şekilde kesilmesi.