Ana içeriğe geç
Modül 5 · Ders 2 ders 5Kurstaki 22/50~14 min
Modül dersleri (2/5)

Yöntemler: değer ve işaretçi alıcısı

Go'daki bir yöntem, alıcı içeren bir işlevdir: özel bir func ile yöntem adı arasında bildirilen parametre; bir türe yöntem. Sınıf yok: yöntemler tanımlanabilir geçerli pakette bildirilen herhangi bir adlandırılmış tür.

Sözdizimi

Go
type Person struct {
    Name string
}

func (p Person) Greet() string {
    return "ciao " + p.Name
}

p := Person{Name: "Ada"}
fmt.Println(p.Greet())   // "ciao Ada"

Alıcı p Person, Greet'yı Person yöntemi yapar. İçinde yöntemine göre p diğerleri gibi bir değişkendir.

Değer alıcısı ve işaretçi alıcısı

Go
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
    return strings.ToUpper(p.Name)
}

// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
    p.Name = n
}

İşaretçi alıcısıyla alıcıyı değiştirebilir ve değişiklikleri yapabilirsiniz yöntemin dışında görülebilir. Bir değer alıcısıyla bunu yapamazsınız; yalnızca yerel kopyayı değiştirin.

Go
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name)   // "Grace" — change is visible

İşaretçi alıcısı ne zaman kullanılır?

Öncelik sırasına göre pratik kurallar:

  1. Alıcıyı değiştirmelisiniz → işaretçi alıcısı. Zorunlu.
  2. Yapı büyük (içinde onlarca alan, dizi var) → işaretçi Pahalı kopyalardan kaçınmak için alıcı.
  3. Tutarlılık: Türdeki EN AZ bir yöntemin işaretçi alıcısı varsa, şunu kullanın: diğerleri için de bir işaretçi alıcısı. için çok önemli bir kongre arayüzler (Modül 6).
  4. Küçük, değişmez, "değer" türleri (time.Time, karmaşık sayılar, küçük yapılar) → değer alıcısı, daha okunabilir.

Yapısal olmayan türlere ilişkin yöntemler

Paketinizde belirtilen herhangi bir NAMED türündeki yöntemleri tanımlayabilirsiniz:

Go
type Celsius float64

func (c Celsius) ToFahrenheit() float64 {
    return float64(c)*9/5 + 32
}

t := Celsius(20)
fmt.Println(t.ToFahrenheit())  // 68

Bunları diğer paketlerdeki türlerde tanımlayamazsınız (örn. int, string): önce yerel bir adlandırılmış tür oluşturun.

Deneyin

Egzersiz#go.m5.l2.e1
Denemeler: 0Yükleniyor…

Kişiye 'ciao <İsim>' döndüren bir Greet() dize yöntemi (değer alıcısı) ekleyin.

Düzenleyici yükleniyor…
İpucu göster

Yöntem adından ÖNCE parantez içindeki alıcı.

3 denemeden sonra çözüm mevcut

Egzersiz#go.m5.l2.e2
Denemeler: 0Yükleniyor…

p.Name'i değiştiren bir POINTER alıcısına sahip bir Rename(n string) yöntemi ekleyin.

Düzenleyici yükleniyor…
İpucu göster

İşaretçi alıcısı: `(p *Kişi)`.

3 denemeden sonra çözüm mevcut

Quiz#go.m5.l2.e3
Hazır

İşaretçi alıcısını ne zaman kullanmalısınız (p *T)?

Go
func (t ?T) M() { ... }
Cevap seçenekleri

Özet

  • Yöntem = alıcıyla işlev: func (r T) Name(...) ... { ... }.
  • Değer alıcısı: bir kopya üzerinde çalışır; İşaretçi alıcısı: orijinal üzerinde çalışır.
  • Go, çağrı sitesinde T ↔ *T dönüşümünü otomatik olarak gerçekleştirir.
  • İşaretçi alıcısı şu durumlarda: mutasyon + büyük yapı + türün diğer yöntemleriyle tutarlılık.
  • Değer ve işaretçi alıcılarını asla aynı tipte karıştırmayın.
  • Yöntemler geçerli paketteki NAMED türlerine devam eder (yapısal olmayanlar dahil).