С помощью какого механизма в Go метод связывается со структурой? Что такое получатель (receiver)?

Ответ

В Go метод связывается с определенным типом (чаще всего со структурой) с помощью получателя (receiver).

Получатель — это специальный параметр в объявлении функции, который указывается перед её именем. Он превращает обычную функцию в метод конкретного типа.

Существует два типа получателей:

  1. Получатель-значение (value receiver)
  2. Получатель-указатель (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 предоставляет синтаксический сахар: вы можете вызывать методы с получателем-указателем на значениях и наоборот. Компилятор автоматически возьмёт адрес значения или разыменует указатель, где это возможно.