Ответ
В Go память для переменных, объявленных в функции, выделяется либо в стеке (stack), либо в куче (heap). Решение принимает компилятор на этапе компиляции в процессе, который называется анализ на утечку (escape analysis).
1. Выделение в стеке (Stack Allocation)
Это стандартное поведение для большинства локальных переменных. Стек — это быстрая, самоочищающаяся область памяти. Память выделяется при входе в функцию и автоматически освобождается при выходе из нее.
Пример:
func calculateSum() int {
a := 5 // 'a' создается в стеке
b := 10 // 'b' создается в стеке
return a + b
} // Память под 'a' и 'b' освобождается здесь
2. Выделение в куче (Heap Allocation / "Escape")
Если компилятор определяет, что переменная должна "пережить" вызов функции (например, на нее остается ссылка вне функции), он перемещает ее в кучу. Память в куче управляется сборщиком мусора (Garbage Collector).
Причины "утечки" в кучу:
- Возврат указателя на локальную переменную.
- Захват переменной замыканием (closure), которое переживает функцию.
- Сохранение ссылки на переменную в глобальной переменной или передача в другую горутину.
Пример:
func createUser(name string) *User {
u := User{Name: name} // 'u' будет создана в куче
return &u // т.к. мы возвращаем указатель на нее
}
Вывод: По умолчанию переменные создаются в стеке для максимальной производительности. Если переменная должна существовать после завершения функции, компилятор перемещает её в кучу.