Ответ
Слайс в Go — это структура-заголовок (slice header), которая содержит указатель на базовый массив, длину (len
) и ёмкость (cap
). Вопрос об аллокации слайса на самом деле сводится к вопросу, где будет размещен его базовый массив.
По умолчанию, базовый массив для слайса аллоцируется в куче (heap).
Однако, компилятор Go проводит анализ побега (escape analysis). Если компилятор определяет, что массив не будет использоваться за пределами функции, в которой он создан (т.е. не "сбегает"), и его размер невелик и известен на этапе компиляции, он может быть аллоцирован на стеке (stack) для повышения производительности.
Ключевые факторы:
- Escape Analysis: Основной механизм, решающий, куда поместить данные.
- Размер данных: Небольшие аллокации с большей вероятностью останутся на стеке.
- Время жизни: Если данные должны пережить вызов функции (например, возвращаются из нее), они будут перемещены в кучу.
Пример:
package main
//go:noinline
func createStackSlice() {
// Этот слайс, скорее всего, будет аллоцирован на стеке.
// Размер известен, и слайс не покидает пределы функции.
stackSlice := make([]int, 10)
_ = stackSlice
}
//go:noinline
func createHeapSlice() []int {
// Этот слайс будет аллоцирован в куче, так как он
// "сбегает" из функции (возвращается наружу).
heapSlice := make([]int, 10)
return heapSlice
}
func main() {
createStackSlice()
_ = createHeapSlice()
}