Go'da yöntemler hem değer (value) hem de türün işaretçisi (pointer) için ilan edilebilir. Bu özellik, verilerin kimler tarafından değiştirileceğine açık bir kontrol sağlamak için dilin erken sürümlerinden beri korunmuştur. Klasik sorun, değer (değişmez) ve işaretçi (verilere ortak erişim ve değiştirme imkanı) semantiği arasındaki mesafeyi gerektirmektedir.
Sorun — Değer alıcı ile bir yöntemi ilan etmek ve beklenen etkiyi elde edememek ya da işaretçi değişkeninde değer yöntemini çağırmak kolaydır.
Çözüm — Aşağıdaki kurallara uyun:
Kod örneği:
type Counter struct { Value int } func (c Counter) IncCopy() { c.Value++ } // değer alıcı func (c *Counter) IncPointer() { c.Value++ } // işaretçi alıcı c := Counter{} c.IncCopy() // Değer 0 kalacak c.IncPointer() // Değer 1 olacak
Anahtar özellikler:
Bir işaretçi üzerinde değer alıcı yöntemi ve bir değer üzerinde işaretçi yöntemini çağırmak mümkün mü?
Go, "kaputun altında" otomatik olarak işaretçileri derecelendirir veya adreslerini alır, bu nedenle çağrı uygun olduğunda yapılabilir. Ancak her zaman böyle olmaz — arayüzlerle bu aynı şekilde öngörülebilir değildir.
var c Counter (&c).IncCopy() // İşaretçi üzerinden değer yöntemini çağırabilirsiniz c.IncPointer() // İşaretçi yöntemini çağırabilirsiniz, Go otomatik olarak adresi alır
Eğer yapı yalnızca işaretçi yöntemlerini uyguluyorsa ama arayüzde değer olarak geçerse ne olur?
Bu tür bir nesne, işaretçi yöntemlerini gerektiriyorsa arayüzü uygulamaz, bu nedenle panic veya derleme hatası mümkündür.
type D interface { IncPointer() } func f(d D) {} c := Counter{} f(c) // hata! Counter değeri arayüzü uygulamaz f(&c) // doğru
İşaretçi alıcı yöntemi çağrıldığında, eğer işaretçinin kopyası geçtilerse yapı değişir mi?
Evet, işaretçi kopyalansa bile altındaki nesne aynı kalır — sonuç birbirinin aynısı olacaktır.
c := Counter{} p := &c p2 := p p2.IncPointer() // Değer artar
Mühendis, "Update" yöntemleri ile değer alıcı içeren bir yapı uygular. Arayüz üzerinden yapı geçildiğinde, değişiklikler "kaybolur" — çünkü kopya ile çalışılır.
Artıları:
Eksileri:
Ekipte açık bir anlaşma: durum değişikliğini içeren tüm yöntemler yalnızca işaretçi alıcıdır, arayüzler yalnızca işaretçilerle uygulanır, değer — "genişletmeler" ve yardımcılar için.
Artıları:
Eksileri: