Ce face metode
O metodă este o funcție cu un parametru special, receptorul, scris între paranteze înaintea numelui: func (c Cerc) Aria() float64. Se apelează cu punct: c.Aria(). Metode se pot adăuga oricărui tip definit în același pachet, nu doar struct-urilor (type Lei float64 poate avea metode).
Cu receptor valoare ((c Cerc)) metoda lucrează pe o copie. Cu receptor pointer ((c *Cont)) metoda poate modifica originalul și evită copierea. Regula practică: dacă vreo metodă trebuie să modifice valoarea, folosește receptor pointer la toate metodele tipului.
Go face automat conversia la apel: pe o variabilă c poți apela o metodă cu receptor pointer (c.Depune(10) devine (&c).Depune(10)). Metodele determină ce interfețe implementează un tip; o metodă String() string schimbă felul în care fmt afișează valoarea.
Exemple
Exemplul 1: Receptor valoare și receptor pointer
Depune modifică soldul pentru că primește pointer; Descriere doar citește.
package main
import "fmt"
type Cont struct {
Titular string
Sold float64
}
func (c *Cont) Depune(suma float64) {
c.Sold += suma
}
func (c *Cont) Retrage(suma float64) bool {
if suma > c.Sold {
return false
}
c.Sold -= suma
return true
}
func (c Cont) Descriere() string {
return fmt.Sprintf("%s: %.2f lei", c.Titular, c.Sold)
}
func main() {
c := Cont{Titular: "Ana"}
c.Depune(300)
fmt.Println(c.Retrage(500), c.Retrage(120))
fmt.Println(c.Descriere())
}
Rezultat
false true
Ana: 180.00 lei
Exemplul 2: Metoda String() și metode pe tipuri simple
fmt apelează automat String() la afișare.
package main
import "fmt"
type Temperatura float64
func (t Temperatura) Fahrenheit() float64 {
return float64(t)*9/5 + 32
}
func (t Temperatura) String() string {
return fmt.Sprintf("%.1f °C", float64(t))
}
func main() {
azi := Temperatura(23.5)
fmt.Println("azi:", azi)
fmt.Println("în Fahrenheit:", azi.Fahrenheit())
}
Rezultat
azi: 23.5 °C
în Fahrenheit: 74.3
Greșeli frecvente
- Receptor valoare la o metodă care trebuie să modifice: schimbarea se face pe copie și se pierde.
- Amestecarea receptorilor valoare și pointer pe același tip: poate face ca doar
*T(nu șiT) să implementeze o interfață. - Metode pentru tipuri din alt pachet:
cannot define new methods on non-local type string. String()care apeleazăfmt.Sprint(t)pe același tip: recursivitate infinită.
Comenzi înrudite
struct și struct-uri: Grupează mai multe câmpuri cu nume și tipuri diferite într-un singur tip; baza pentru modelarea datelor în Go.interface și interfețe: Interfața descrie un set de metode; orice tip care le are o implementează automat, fără declarație explicită.pointeri (* și &): Un pointer (*T) ține adresa unei variabile; prin el funcțiile pot modifica valoarea originală.embedding (încorporare): Include un tip în altul fără nume de câmp; câmpurile și metodele lui devin accesibile direct (compoziție).