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 main
2import "fmt"
3
4type SelfReference struct {
5self *SelfReference
6}
7
8func make() SelfReference {
9s:= SelfReference{}
10s.self = &s
11return s
12}
13
14func 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ı.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası

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.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz