我不太明白为什么 Go 的转义分析说,当传递fmt.Fprintln
给与fmt.Fprintln
. 我希望下面的两个场景 A 和 B 应该让问题更清楚。
场景A:x
逃逸到堆
取如下内容main.go
:
package main
import (
"fmt"
"os"
)
func main() {
x := 73
fmt.Fprintln(os.Stdout, x)
}
现在运行时,go build -gcflags "-m"
您会看到指示x
逃逸到堆的输出。输出说明了一些类似的内容
...
.\main.go:10:14: x escapes to heap
...
场景B:x
不逃到堆
现在取以下内容main.go
:
package main
import (
"io"
"os"
)
func main() {
x := 73
myOwnPrintFunction(os.Stdout, x)
}
//go:noinline
func myOwnPrintFunction(w io.Writer, a ...interface{}) {
println(a)
}
再次运行go build -gcflags "-m"
,您会看到一个输出,表明x
不再逃逸到堆中。输出现在说了一些类似的东西
...
.\main.go:10:20: x does not escape
...
我不明白这里的区别。我会认为场景 A 是正确的,因为x
它被传递给一个接受任意数量interface{}
参数的可变参数函数。但显然这是错误的,因为变量在传递给自写函数时不再转义,该函数myOwnPrintFunction
也是一个接受任意数量interface{}
参数的可变参数函数,编译器被指示不要内联这个简单的函数。