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

Как в Go передаются аргументы и зачем нужны указатели?

JuniorОсновы языка
Ещё спрашивают так:
  • Всё ли в Go передаётся по значению?
  • Почему изменение структуры в функции не видно снаружи?
Коротко

Всё передаётся по значению — копируется само значение: структура целиком, массив целиком. Чтобы функция изменила объект вызывающего, передают указатель (*T, взять адрес — &x). Срезы, мапы и каналы — маленькие дескрипторы, ссылающиеся на общие данные, поэтому изменения элементов видны снаружи.

  • Нет арифметики указателей (кроме unsafe)
  • Можно вернуть указатель на локальную переменную — компилятор разместит её в куче
  • Большие структуры передают указателем, чтобы не копировать

А ещё append в функции не виден снаружи, если не вернуть новый срез

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

Попробуйте сами

Срезы Go: len, cap, append и общий массив

Подробно

Копирование значений. Присваивание и передача в функцию копируют значение. Для структуры из десяти полей копируются все десять, для массива [1000]int — тысяча чисел.

Указатель хранит адрес. Через него функция работает с оригиналом. Обращение к полю через указатель пишется так же: u.Name (Go разыменовывает автоматически).

Ссылочные по поведению типы. Срез — структура {указатель на массив, длина, ёмкость}; копия среза указывает на тот же массив, поэтому xs[0] = 1 в функции виден снаружи. Но append, создавший новый массив, меняет только локальную копию дескриптора. Мапа и канал — тоже указатели на внутренние структуры.

Когда указатель: нужно изменить объект; структура большая; нужно различать «нет значения» (nil). Для маленьких неизменяемых значений передача по значению проще и безопаснее.

Пример

type User struct{ Name string }

func rename(u User)     { u.Name = "Петя" }   // меняет копию
func renameP(u *User)   { u.Name = "Петя" }   // меняет оригинал

u := User{Name: "Вася"}
rename(u)    // u.Name == "Вася"
renameP(&u)  // u.Name == "Петя"

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

  • Передача по значению всегда.
  • Указатели для изменения и больших структур.
  • Почему срезы и мапы ведут себя как ссылки.

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

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

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

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

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