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
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ı
// 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.
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:
- Alıcıyı değiştirmelisiniz → işaretçi alıcısı. Zorunlu.
- Yapı büyük (içinde onlarca alan, dizi var) → işaretçi Pahalı kopyalardan kaçınmak için alıcı.
- 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).
- 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:
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
t := Celsius(20)
fmt.Println(t.ToFahrenheit()) // 68Bunları diğer paketlerdeki türlerde tanımlayamazsınız (örn. int, string):
önce yerel bir adlandırılmış tür oluşturun.
Deneyin
Kişiye 'ciao <İsim>' döndüren bir Greet() dize yöntemi (değer alıcısı) ekleyin.
İpucu göster
Yöntem adından ÖNCE parantez içindeki alıcı.
3 denemeden sonra çözüm mevcut
p.Name'i değiştiren bir POINTER alıcısına sahip bir Rename(n string) yöntemi ekleyin.
İpucu göster
İşaretçi alıcısı: `(p *Kişi)`.
3 denemeden sonra çözüm mevcut
İşaretçi alıcısını ne zaman kullanmalısınız (p *T)?
func (t ?T) M() { ... }Ö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↔*Tdö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).