Распределение стека и куча структур в Go и как они связаны со сборкой мусора
Я новичок в Go и испытываю небольшой диссонанс между программированием на основе стека в стиле C, когда автоматические переменные живут в стеке, а выделенная память - в куче, и программированием на основе стека в стиле Python, где единственное, что живет в стеке - это ссылки / указатели на объекты в куче.
Насколько я могу судить, две следующие функции дают одинаковый вывод:
func myFunction() (*MyStructType, error) {
var chunk *MyStructType = new(HeaderChunk)
...
return chunk, nil
}
func myFunction() (*MyStructType, error) {
var chunk MyStructType
...
return &chunk, nil
}
То есть. выделить новую структуру и вернуть ее.
Если бы я написал это в C, первый поместил бы объект в кучу, а второй поместил бы его в стек. Первый вернул бы указатель на кучу, второй вернул бы указатель на стек, который испарился бы к моменту возврата функции, что было бы плохо.
Если бы я написал это на Python (или во многих других современных языках, кроме C #), пример 2 был бы невозможен.
Я понял, что сборщик мусора Go собирает оба значения, поэтому обе вышеуказанные формы в порядке.
Цитировать
Обратите внимание, что, в отличие от C, вполне нормально возвращать адрес локальной переменной; хранилище, связанное с переменной, сохраняется после возврата из функции. Фактически, взятие адреса составного литерала выделяет новый экземпляр каждый раз, когда он оценивается, поэтому мы можем объединить эти две последние строки.
http: //golang.org/doc/effective_go.html#function
Но это вызывает пару вопросов.
1 - В примере 1 структура объявлена в куче. Как насчет примера 2? Это объявляется в стеке так же, как это было бы в C, или это тоже происходит в куче?
2 - Если пример 2 объявлен в стеке, как он остается доступным после возврата функции?
3 - Если пример 2 действительно объявлен в куче, как получается, что структуры передаются по значению, а не по ссылке? Какой смысл указателей в этом случае?