Golang闭包访问闭包外的变量

huangapple go评论70阅读模式
英文:

Golang closure access variables outside of closure

问题

在使用闭包的以下代码中,变量m和n是在堆栈上还是在堆上?

func main() {
	var m, n int

	add := func() int {
		return m + n
	}

	fmt.Println(add())
}

在这段代码中,变量m和n都是在堆栈上分配的。闭包函数add引用了外部函数main中的变量m和n,但它们仍然是在堆栈上分配的。

英文:

In the following code which uses closure, variable m and n are on stack or heap?

func main() {
	var m, n int

	add := func() int {
		return m + n
	}

	fmt.Println(add())
}


答案1

得分: 1

你可以使用以下标志构建你的代码:

go build -gcflags="-m"

然后查看实际发生的情况。在这个特定的案例中,对于整个文件:

package main

import "fmt"

func main() {
	var m, n int

	add := func() int {
		return m + n
	}

	fmt.Println(add())
}

输出如下(go版本 go1.18 darwin/arm64):

./main.go:8:9: 可以内联 main.func1
./main.go:12:17: 内联调用 main.func1
./main.go:12:13: 内联调用 fmt.Println
./main.go:8:9: 函数字面量不逃逸
./main.go:12:13: ... 参数不逃逸
./main.go:12:17: ~R0 逃逸到堆上

所以 m 和 n 不会逃逸到堆上,但调用 add 的结果会逃逸。

英文:

You can build your code with following flags:

go build -gcflags="-m"

and see what is actually happening. In this particular case for the whole file:

package main

import "fmt"

func main() {
	var m, n int

	add := func() int {
		return m + n
	}

	fmt.Println(add())
}

the output is as follows (go version go1.18 darwin/arm64):

./main.go:8:9: can inline main.func1
./main.go:12:17: inlining call to main.func1
./main.go:12:13: inlining call to fmt.Println
./main.go:8:9: func literal does not escape
./main.go:12:13: ... argument does not escape
./main.go:12:17: ~R0 escapes to heap

So m and n don't escape to heap, but the result of calling add does escape.

huangapple
  • 本文由 发表于 2022年8月1日 00:24:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/73184994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定