Ответ
В Go метод связывается с определенным типом (чаще всего со структурой) с помощью получателя (receiver).
Получатель — это специальный параметр в объявлении функции, который указывается перед её именем. Он превращает обычную функцию в метод конкретного типа.
Существует два типа получателей:
- Получатель-значение (value receiver)
- Получатель-указатель (pointer receiver)
type User struct {
Name string
Age int
}
// Метод с получателем-значением (value receiver)
// Работает с копией структуры `User`.
// Изменения `u.Name` внутри метода не повлияют на оригинал.
func (u User) GetName() string {
return u.Name
}
// Метод с получателем-указателем (pointer receiver)
// Работает с указателем на оригинальную структуру `User`.
// Может изменять состояние исходного объекта.
func (u *User) SetName(name string) {
u.Name = name
}
Ключевые различия и когда что использовать:
Изменение состояния: Если метод должен изменять данные в структуре-получателе, используйте получатель-указатель (
*User
). Если метод не изменяет данные, а только читает их, достаточно получателя-значения (User
).Производительность: Для больших структур использование получателя-указателя эффективнее, так как это позволяет избежать копирования всей структуры при каждом вызове метода. Передается только указатель (адрес в памяти).
Согласованность: Принято придерживаться единого стиля для типа. Если хотя бы один метод требует получателя-указателя, то для согласованности остальные методы этого типа также часто объявляют с получателем-указателем.
Go предоставляет синтаксический сахар: вы можете вызывать методы с получателем-указателем на значениях и наоборот. Компилятор автоматически возьмёт адрес значения или разыменует указатель, где это возможно.