这Composite Literal section个提法是:
获取复合文字的地址(§地址运算符)会生成指向文字值实例的唯一指针.
That means the pointer returned by the New
function will be a valid one (allocated on the stack).
Calls:
In a function call, the function value and arguments are evaluated in the usual order.
After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution.
The return parameters of the function are passed by value back to the calling function when the function returns.
你可以看到更多的in this answer和this thread.
正如"Stack vs heap allocation of structs in Go, and how they relate to garbage collection"中提到的:
值得注意的是,"栈"和"堆"这两个词没有出现在语言规范中的任何地方.
这blog post "Escape Analysis in Go"个细节是发生了什么,mentioning the FAQ个:
如果可能,Go编译器将在函数的堆栈框架中为函数分配局部变量
这篇博文补充道:
执行"逸出分析"的代码位于100中.
从概念上讲,它try 确定局部变量是否脱离当前作用域;发生这种情况的只有两种情况,一种是返回变量的地址,另一种是将变量的地址分配给外部作用域中的变量.
如果变量转义,则必须将其分配到堆上;否则,将其放入堆栈是安全的.
有趣的是,这也适用于new(T)
个分配.
如果它们不转义,它们最终将被分配到堆栈上.下面是一个澄清问题的例子:
var intPointerGlobal *int = nil
func Foo() *int {
anInt0 := 0
anInt1 := new(int)
anInt2 := 42
intPointerGlobal = &anInt2
anInt3 := 5
return &anInt3
}
Above, anInt0
and anInt1
do not escape, so they are allocated on the stack;
anInt2
and anInt3
escape, and are allocated on the heap.
另请参阅"Five things that make Go fast":
与C不同的是,C通过在函数范围内声明值,强制您 Select 值是存储在堆上、通过malloc
存储在堆栈上,还是存储在堆栈上,而GO实现了一种称为转义分析的优化.
默认情况下,GO的优化始终处于启用状态.
您可以使用100switch 查看编译器的转义分析和内联决策.
因为转义分析是在编译时执行的,而不是在运行时执行的,所以无论垃圾收集器有多高效,堆栈分配总是比堆分配快.