Как в Go передаются аргументы и зачем нужны указатели?
- Всё ли в Go передаётся по значению?
- Почему изменение структуры в функции не видно снаружи?
Всё передаётся по значению — копируется само значение: структура целиком, массив целиком. Чтобы функция изменила объект вызывающего, передают указатель (*T, взять адрес — &x). Срезы, мапы и каналы — маленькие дескрипторы, ссылающиеся на общие данные, поэтому изменения элементов видны снаружи.
- Нет арифметики указателей (кроме unsafe)
- Можно вернуть указатель на локальную переменную — компилятор разместит её в куче
- Большие структуры передают указателем, чтобы не копировать
А ещё 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 == "Петя"Что хотят услышать
- Передача по значению всегда.
- Указатели для изменения и больших структур.
- Почему срезы и мапы ведут себя как ссылки.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Всё передаётся по значению; чтобы менять объект — указатель
- ✗Структуры передаются по ссылке автоматически, а примитивы — по значению
- ✗В Go есть арифметика указателей
- ✗Возвращать указатель на локальную переменную нельзя
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.