Go'da Pointer Receiver vs Value Receiver: Ne Zaman Hangisini Seçmeli

Go'da bir method yazarken, receiver'ı pointer (*Type) veya value (Type) olarak tanımlayabilirsin. Bu seçim, değerin kopyalanıp kopyalanmayacağını ve orijinal veriyi değiştirebilip değiştiremeyeceğini belirler.

Receiver'ı value olarak tanımlarsan, metod orijinal veriyi değiştirmez. Verinin bir kopyası oluşturulur. Bu, küçük ve immutable (değişmez) yapılar için iyidir.

Örnek:

1type Point struct {
2X, Y int
3}
4
5// Value receiver - orijinal değişmez
6func (p Point) Move(dx, dy int) Point {
7p.X += dx
8p.Y += dy
9return p
10}
11
12func main() {
13p:= Point{1, 2}
14p2:= p.Move(5, 3)
15fmt.Println(p) // {1 2} - değişmedi
16fmt.Println(p2) // {6 5} - yeni değer döndü
17}

Çıktı: {1 2} ve {6 5}

Receiver'ı pointer olarak tanımlarsan, orijinal veriyi doğrudan değiştirebilirsin. Büyük struct'lar, veritabanı bağlantıları veya state'i değişen nesneler için tercih edilir.

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

Örnek:

1type Account struct {
2Balance int
3}
4
5// Pointer receiver - orijinal değişir
6func (a *Account) Withdraw(amount int) {
7a.Balance -= amount
8}
9
10func main() {
11acc:= &Account{Balance: 100}
12acc.Withdraw(30)
13fmt.Println(acc.Balance) // 70 - orijinal değişti
14}

Çıktı: 70

  • Pointer receiver seç eğer:
  • Metod veriyi değiştirmeli
  • Struct büyükse (kopyalamak pahalı)
  • Sync.Mutex gibi copyable olmayan alan varsa
  • Value receiver seç eğer:
  • Metod sadece okuma yapıyorsa
  • Struct küçükse
  • Immutable davranış istiyorsan

Bir struct için receiver türünü karıştırma; tutarlı ol. Eğer bir metod pointer alıyorsa, diğerleri de pointer almalı.

bknz: Go'da Eş Zamanlılık Desenleri: Worker Pool Uygulaması

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz
  • adlı kullanıcıya yanıt verdi
    persembeaksami

    aynen işte tam da bu yüzden başında dikkat etmesen bile sonradan çok sıkıntı oluyor bir

  • adlı kullanıcıya yanıt verdi
    kodkafasi

    evet bu çok önemli fark küçük structlarda görmüyorsun ama bir kaç megabytelık bir şey

  • adlı kullanıcıya yanıt verdi
    persembeaksami

    ben de başta hep value receiver kullanıyordum sonra büyük structlarla çalışmaya başlayınca farkı gördüm açıkçası memoryde ne kadar yer kapladığına

  • adlı kullanıcıya yanıt verdi
    kodkafasi

    aynen ben de genellikle öyle yapıyorum struct büyükse kopya oluşturmak saçma olur zaten

  • persembeaksami

    Pratikte şöyle düşünüyorum eğer struct küçükse ve sadece okumak için kullanacaksan value receiver yeterli Ama değiştirmek gerekiyorsa ya da struct