Получить доступ

Когда метод должен иметь получатель-указатель, а когда — значение?

JuniorМетоды и интерфейсы
Ещё спрашивают так:
  • Почему структура не удовлетворяет интерфейсу, хотя метод есть?
Коротко

Указатель func (s *Svc) — если метод меняет получателя, структура большая или содержит то, что нельзя копировать (sync.Mutex). Значение func (p Point) — для маленьких неизменяемых типов. Получатели одного типа делают единообразными.

  • Методы с получателем-указателем входят в набор методов только *T, а не T
  • Поэтому T не удовлетворяет интерфейсу, если нужный метод объявлен на *T
  • Вызов p.Method() на адресуемой переменной Go сам возьмёт адрес

А ещё Копирование структуры с мьютексом — go vet предупредит (copylocks)

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Получатель-значение получает копию: изменения внутри метода не видны снаружи. Для Point{X, Y} это естественно и безопасно.

Получатель-указатель работает с оригиналом. Нужен, когда метод меняет состояние, когда структура большая (копирование при каждом вызове), когда в ней мьютекс или другие поля, которые нельзя копировать.

Наборы методов. У типа T — методы с получателем T; у *T — и T, и *T. Значение в интерфейсе неадресуемо, поэтому Go не может взять его адрес, чтобы вызвать метод указателя, — отсюда ошибка компиляции «does not implement (method has pointer receiver)».

Правило единообразия: если хотя бы один метод требует указателя, все методы типа обычно объявляют на указателе.

Пример

type Counter struct{ n int }
func (c *Counter) Inc()      { c.n++ }      // меняет — указатель
func (c Counter) Value() int { return c.n }

type Incer interface{ Inc() }
var _ Incer = &Counter{}    // ок
var _ Incer = Counter{}     // ошибка: Inc объявлен на *Counter

Что хотят услышать

  • Критерии выбора.
  • Наборы методов и интерфейсы.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем