Когда использовать указатель
Правила выбора
| Ситуация | Рекомендация |
|---|---|
| Функция должна изменить переменную вызывающего кода | указатель |
| Структура больше ~64 байт | указатель (избегаем копирования) |
| Нужно выразить «нет значения» (optional) | указатель (можно nil) |
| Маленький тип, функция только читает | значение |
| Срез, карта, канал | значение (они уже содержат указатель внутри) |
Структуры и указатели
Метод с pointer-receiver может изменять поля структуры; с value-receiver — нет:
type Counter struct{ n int }
func (c *Counter) Inc() { c.n++ } // изменяет оригинал
func (c Counter) Val() int { return c.n }
Если хоть один метод объявлен с *T, все остальные методы того же типа обычно тоже делают pointer-receiver — для консистентности.
Escape-анализ
Go сам решает, выделить переменную на стеке или в куче. Явно управлять этим, как в C, не нужно. Вернуть указатель на локальную переменную — безопасно:
func newPoint(x, y float64) *Point {
return &Point{x, y} // компилятор перенесёт в кучу
}
Упражнения
| № | Задание | Сложность |
|---|---|---|
| 1 | Упражнение 1 | medium |
| 2 | Упражнение 2 | medium |