Metodele pointerelor
La apelarea unei metode, obiectul structurii pentru care este definită metoda este transmis în ea prin valoare. Ce înseamnă acest lucru? Să analizăm următorul exemplu:
package main
import "fmt"
type person struct{
name string
age int
}
func (p person) updateAge(newAge int){
p.age = newAge
}
func main() {
var tom = person { name: "Tom", age: 24 }
fmt.Println("before", tom.age)
tom.updateAge(33)
fmt.Println("after", tom.age)
}
Pentru structura person este definită metoda updateAge, care primește parametrul newAge și modifică valoarea câmpului age al structurii. Adică, la apelarea acestei metode, ne așteptăm ca vârsta persoanei să se schimbe. Totuși, ieșirea în consolă ne arată că valoarea câmpului age nu se schimbă:
before 24
after 24
Acest lucru se întâmplă pentru că la apelul tom.updateAge(33), metoda updateAge primește o copie a structurii tom. Adică, structura tom este copiată într-o altă locație din memorie, iar mai departe metoda updateAge lucrează cu copia, fără a afecta structura originală tom.
Totuși, acest comportament poate fi neintenționat. Ce facem dacă dorim totuși să schimbăm astfel starea structurii? În acest caz, este necesar să folosim pointere la structuri:
package main
import "fmt"
type person struct{
name string
age int
}
func (p *person) updateAge(newAge int){
(*p).age = newAge
}
func main() {
var tom = person { name: "Tom", age: 24 }
var tomPointer *person = &tom
fmt.Println("before", tom.age)
tomPointer.updateAge(33)
fmt.Println("after", tom.age)
}
Acum, metoda updateAge primește un pointer la structura person: p *person, adică de fapt adresa structurii în memorie. Cu ajutorul operației de dereferențiere obținem valoarea la această adresă din memorie și modificăm câmpul age:
(*p).age = newAge
În funcția main definim un pointer la structura person și îi transmitem adresa structurii tom:
var tomPointer *person = &tom
Apoi apelăm metoda updateAge:
tomPointer.updateAge(33)
Astfel, metoda updateAge va primi adresa stocată în tomPointer și va accesa structura tom la acea adresă, modificând valoarea proprietății age.
before 24
after 33
Este important de menționat că, deși metoda updateAge este definită pentru un pointer la structura person, putem totuși apela această metodă și pentru un obiect person:
var tom = person { name: "Tom", age: 24 }
fmt.Println("before", tom.age) // before 24
tom.updateAge(33)
fmt.Println("after", tom.age) // after 33