Go'da Pointer Sürprizi: Struct Kopyalama ve Self-Reference
Go'da değer türleri (value types) ile çalışırken Java veya Rust geçmişinden gelenler sık sık şaşırıyor. Özellikle struct'ın kendisine işaret eden bir pointer içermesi durumunda ilginç bir davranış ortaya çıkıyor.
Bu kod parçasını çalıştırdığında ne olur?
1package main2import "fmt"34type SelfReference struct {5self *SelfReference6}78func make() SelfReference {9s:= SelfReference{}10s.self = &s11return s12}1314func main() {15s:= make()16fmt.Println(s == *s.self, &s == s.self)17}Çıktı: `true false`
İlk değer `true` çıkıyor çünkü `s` ile `s.self` aslında aynı veriye sahip, struct'ın içeriği özdeş. Ancak ikinci değer `false` çıkıyor ve burası kafa karıştırıcı.
Ne oluyor? `make()` fonksiyonu içinde `s` yerel bir değişken. Fonksiyon bu struct'ı döndürdüğünde, Go bir kopya yaratıyor. Yani `s.self` pointer'ı orijinal yerel `s` değişkenine işaret ediyor, ama `main()` fonksiyonundaki `s` başka bir bellek adresidir. Pointer'lar farklı adresleri gösteriyor: biri fonksiyon stack'inin içindeki orijinal nesneyi, diğeri main'deki kopyayı.
Java'da her şey referans olduğu için bu sorun yoktur. Rust'ta ise derleyici bu tür hataları compile zamanında yakalar. Go ise çalışma zamanında sessiz kalıyor.
Bu tuzaktan kaçmak için struct'ı pointer olarak döndür: `func make() SelfReference { s:= &SelfReference{}; s.self = s; return s }`. Böylece aynı bellek adresi döner ve pointer'lar tutarlı kalır.
0 yorum