Я новичок в 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, вполне нормально возвращать адрес локальной переменной; хранилище, связанное с переменной, сохраняется после возврата из функции. Фактически, взятие адреса составного литерала выделяет новый экземпляр каждый раз, когда он оценивается, поэтому мы можем объединить эти две последние строки.
Но это поднимает пару вопросов.
1 - В примере 1 структура объявлена в куче. Как насчет примера 2? Это объявляется в стеке так же, как в C, или оно тоже идет в кучу?
2 - Если пример 2 объявлен в стеке, как он остается доступным после возврата функции?
3 - Если пример 2 действительно объявлен в куче, как получается, что структуры передаются по значению, а не по ссылке? Какой смысл указателей в этом случае?