Ресивер по значению или указателю
Вопрос
Как вы выбираете между ресивером по значению и по указателю? Какие последствия у выбора?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Указатель, если метод меняет состояние
Указатель для больших структур, чтобы не копировать
Указатель, если внутри мьютекс или другое некопируемое
Не смешивать: если один метод на указателе, все на указателе
Выбор влияет на набор методов и реализацию интерфейсов
Значение для маленьких неизменяемых типов (time.Time, точки)
Что могут спросить следом
- Можно ли вызвать pointer-метод у элемента мапы?
- Можно ли вызвать метод на nil-указателе?
Разбор
Указатель беру, когда метод должен изменить ресивер: с ресивером по значению изменения уйдут в копию. Ещё указатель нужен, если структура большая, чтобы не копировать её при каждом вызове, и если в ней есть мьютекс или другой тип, который нельзя копировать. По значению оставляю маленькие неизменяемые типы вроде time.Time или координат, их копировать даже дешевле, чем ходить по указателю. Стараюсь не смешивать: если хоть один метод на указателе, делаю все на указателе, чтобы набор методов был предсказуем. Важное последствие: методы на указателе не входят в набор методов значения, поэтому в интерфейс придётся класть &T{}. И у неадресуемого значения, например элемента мапы, pointer-метод не вызвать. Метод на nil-указателе вызвать можно, он упадёт только если обратится к полям.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Интерфейс с nil-указателем не равен nil
Следующий вопрос
Приведение типа интерфейса без ok
Ещё по теме «Структуры, методы и интерфейсы»
- LRU-кеш на Go: map и двусвязный список
- Очередь с приоритетом через container/heap на Go
- Площади фигур через интерфейс Shape на Go
- Сортировка структур по нескольким ключам на Go
- Что выведет Go: встраивание и вызов метода
- Что выведет Go: интерфейс хранит копию значения
- Что выведет Go: method value и defer копируют ресивер
- Что выведет Go: nil-указатель в интерфейсе error