Назад к урокам

Функции-получатели (Receiver-functions) в Go

Урок объясняет, что такое функции-получатели в Go, как работают value и pointer receivers, чем они отличаются, как receivers позволяют использовать точечную нотацию и улучшать API структур.

Начинающий10 min

🧩 Функции-получатели (Receiver Functions) в Go

Функции-получатели позволяют привязывать методы к структурам и тем самым создавать более удобный и «объектный» стиль работы с данными. Они дают возможность использовать точечную нотацию, скрывать детали реализации и изменять состояние структуры.


📌 Что такое функция‑получатель?

Функция-получатель - это обычная функция, у которой появляется специальный аргумент‑получатель, записанный перед именем функции:

func (c Coordinate) Shift() { ... }

Получатель может быть: - значением (value receiver), - указателем (pointer receiver).

Это определяет, может ли метод изменять структуру.


🧱 Пример структуры

type Coordinate struct {
    X, Y int
}

🔧 Обычная функция (без receiver)

Так выглядит обычная функция, которая изменяет структуру через указатель:

func shiftBy(x, y int, coord *Coordinate) {
    coord.X += x
    coord.Y += y
}

Использование:

coord := Coordinate{5, 5}
shiftBy(1, 1, &coord) // (6, 6)

🔁 Функция‑получатель (указатель)

Получатель‑указатель позволяет менять структуру напрямую:

func (coord *Coordinate) shiftBy(x, y int) {
    coord.X += x
    coord.Y += y
}

Использование:

coord := Coordinate{5, 5}
coord.shiftBy(1, 1) // (6, 6)

Отличительная особенность: вызывается через точечную нотацию.


🧠 Сравнение двух подходов

Оба варианта работают, но:

🟦 Обычная функция

  • нужно передавать адрес вручную,
  • синтаксис менее удобный.

🟩 Функция‑получатель (pointer receiver)

  • изменяет структуру напрямую,
  • удобная точечная нотация,
  • более «методный» стиль.

Пример из слайда показывает, что вызов:

coord.shiftBy(1, 1)

меняет структуру так же, как:

shiftBy(1, 1, &coord)

🧩 Получатель‑значение (value receiver)

Получатель‑значение не меняет структуру, потому что работает с копией:

func (c Coordinate) ShiftDist(other Coordinate) Coordinate {
    return Coordinate{other.X - c.X, other.Y - c.Y}
}

Использование:

first := Coordinate{2, 2}
second := Coordinate{1, 5}

distance := first.ShiftDist(second) // {-1 3}

Value receiver удобен, когда: - метод не должен изменять структуру, - структура маленькая, - важна неизменность данных.


📘 Итоги

  • Receiver‑функции добавляют структурам удобную точечную нотацию.
  • Pointer receiver (*T) позволяет изменять структуру.
  • Value receiver (T) работает с копией, а не с оригиналом.
  • Методы повышают удобство API и читаемость.
  • Часто используется pointer receiver, особенно если структура изменяется.