Method & Receiver
Menambahkan perilaku pada tipe dengan value receiver dan pointer receiver.
Method = function yang menempel pada tipe
Go tidak memiliki class. Sebagai gantinya, kamu menulis method: function dengan tambahan receiver di antara func dan nama.
type Persegi struct {
Sisi float64
}
func (p Persegi) Luas() float64 {
return p.Sisi * p.Sisi
}
s := Persegi{Sisi: 4}
fmt.Println(s.Luas()) // 16
(p Persegi) berarti method Luas dimiliki tipe Persegi, dan di dalamnya objeknya bernama p.
Value receiver vs pointer receiver
Value receiver (p Persegi) | Pointer receiver (p *Persegi) | |
|---|---|---|
| --- | --- | --- |
| Yang diterima | salinan struct | alamat struct asli |
| Bisa mengubah data asli? | Tidak | Ya |
| Cocok untuk | membaca data, struct kecil | mengubah data, struct besar |
func (p *Persegi) Skala(k float64) {
p.Sisi = p.Sisi * k // mengubah Persegi asli
}
s := Persegi{Sisi: 4}
s.Skala(2)
fmt.Println(s.Sisi) // 8
Go otomatis mengubah s.Skala(2) menjadi (&s).Skala(2), jadi kamu tidak perlu menulis & sendiri.
Konsistensi
Jika satu method memakai pointer receiver, sebaiknya semua method tipe itu memakai pointer receiver agar tidak membingungkan.
Method pada tipe non-struct
Method bisa dibuat untuk tipe apa pun yang kamu definisikan sendiri:
type Suhu float64
func (s Suhu) Fahrenheit() float64 {
return float64(s)*9/5 + 32
}
Method String()
Jika sebuah tipe punya method String() string, fmt.Println akan memakainya untuk mencetak:
func (p Persegi) String() string {
return fmt.Sprintf("Persegi sisi %.0f", p.Sisi)
}
(Method ini memenuhi interface fmt.Stringer.)
Constructor
Go tidak punya constructor khusus. Konvensinya function bernama NewXxx:
func NewPersegi(sisi float64) *Persegi {
return &Persegi{Sisi: sisi}
}