Распределение структур в стеке и куче в 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/efficient_go.html#functions

Но возникает пара вопросов.

1 — В примере 1 структура объявлена ​​в куче. А пример 2? Объявлено ли это в стеке так же, как в C, или оно также находится в куче?

2 - Если пример 2 объявлен в стеке, как он остается доступным после возврата функции?

3. Если пример 2 фактически объявлен в куче, как получается, что структуры передаются по значению, а не по ссылке? Какой смысл в указателях в этом случае?

146
задан user 21 November 2015 в 19:54
поделиться