Go: Указатели

9 вопросов

1 Зачем нужен указатель в получателе метода (*T)?

Чтобы метод мог изменять получателя и избежать копирования большой структуры. Вызов возможен и для T, и для *T. При вызове для значения компилятор передаёт адрес. Единообразие: если один метод с *T, обычно все методы получателя делают с *T.

Открыть отдельно →
2 Есть ли в Go арифметика указателей?

Нет. Нельзя прибавлять к указателю число, вычитать указатели (кроме unsafe). Безопасность и упрощение модели памяти. Для обхода слайса используют индекс; для низкоуровневого доступа - пакет unsafe (не рекомендуется без необходимости).

Открыть отдельно →
3 В чём преимущество указателя на int по сравнению с int?

Функция может изменить значение по месту; передаётся только адрес (8 байт), не копируется значение. Общие данные между вызывающим и функцией. Для int редко нужно; чаще указатели для структур, когда нужно мутировать или структура большая.

Открыть отдельно →
4 Когда передавать структуру по значению, когда по указателю?

По значению: маленькие структуры, неизменяемые данные, не хотим мутировать. По указателю: большие структуры (меньше копирования), нужно изменить получателя, структура содержит мьютекс/слайс/map (копирование мьютекса небезопасно). Методы с pointer receiver позволяют мутировать.

Открыть отдельно →
5 Какие типы можно изменять без указателя?

Слайсы, map, каналы - заголовки; при присваивании копируется заголовок, данные общие. Добавление в слайс, изменение map видно снаружи. Но заменить сам слайс/map (переназначить переменную) снаружи нельзя - только содержимое. Для структур и примитивов изменение внутри функции без указателя не видно снаружи.

Открыть отдельно →
6 Что делает оператор * для указателя?

Разыменование: *p даёт значение по адресу p. Чтение или запись: x = *p, *p = x. Для nil указателя *p вызывает панику. Оператор & даёт адрес переменной: p := &x.

Открыть отдельно →
7 Что такое nil pointer dereference?

Обращение по нулевому указателю: *p или вызов метода через p.M(), когда p == nil. Вызывает панику. Нужно проверять указатель перед использованием или гарантировать инициализацию. Частая причина - неинициализированная структура или ошибочное предположение о возвращаемом значении.

Открыть отдельно →
8 Как решается, выделять ли переменную на стеке или в куче?

Компилятор выполняет escape analysis: если указатель на переменную "убегает" (возвращается, сохраняется в глобальную переменную, передаётся в канал и т.д.), переменная размещается в куче. Иначе - на стеке. Разработчик не задаёт явно; можно смотреть через go build -gcflags="-m".

Открыть отдельно →
9 Что показывает unsafe.Sizeof?

unsafe.Sizeof(x) возвращает размер в байтах, занимаемый значением типа x (или переменной x). Размер типа без учёта косвенно указываемых данных (для слайса - заголовок, не длина массива). Выравнивание может добавлять padding в структурах. Пакет unsafe - для низкоуровневого кода.

Открыть отдельно →
🧠Квиз 🏆Лидеры 🎯Собесед. 📖Вопросы 📚База зн.