goroutine传值和用外部变量有区别吗?

```go func foo() { a : = 'aaaaa' b := 'bbbb' //一些其他逻辑 f := 1 go func(){ fmt.Println(f) }() } ``` 和 ```go func foo() { a : = 'aaaaa' b := 'bbbb' //一些其他逻辑 f := 1 go func(f int){ fmt.Println(f) }(f) } ``` 知道第二种传值一般在for循环的时候传递 k 值,比较好奇的是,第一种系统回收 a 和 b 的内存会受影响吗
已邀请:

liunian - root

赞同来自: dncmn keepeye

- 第一种是指向外部作用域中的 f 变量
- 第二种是函数自身作用域中的 f 变量

simple - 既要有梦想,又要有实力

赞同来自: keepeye Mrwxj

用这个编译命令试试:**go build -gcflags '-m -l'** (逃逸分析)

第一种写法(闭包)编译器会将变量f移动**heap**中,因为会用两个goroutine要访问f;
第二种写法变量f只需要在调用foo函数的goroutine的**stack**上就可以了。

changjixiong - 时常做白日梦的程序员

赞同来自: keepeye

你需要先分清楚形参、实参
以及变量的作用域

g0194776

赞同来自: keepeye

我的理解是,第一种和第二种不会由于GC的原因导致数据无法访问。

但是这两种方式的差距在哪里呢?我认为在于变量引用的安全性。
相较第一种,第二种方式由于是传递的变量所以在goroutine外侧所使用的变量即便引用被改变,也不会影响到goroutine里面的值。

而如果是第一种方式的话,外面的f一旦改变,则里面的也可能会受到影响。

wangxingge

赞同来自: keepeye

答案大家都说的很清楚了,建议再看一下这个系列的文章,就会更了解原理。
https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html

要回复问题请先登录注册