Go语言 当一个变量超出了循环、条件或case的作用域时会发生什么?

p3rjfoxz  于 2023-05-20  发布在  Go
关注(0)|答案(2)|浏览(144)

这个问题的原因只是我的好奇心,以确定什么可能是最好的做法,写一个高性能的流消费者阅读大尺寸字节数组从多个通道。(尽管过早优化是万恶之源,但这更多的是一种好奇心)。我读过关于Chere的类似senario的答案,但我要求具体的答案,因为它是一种垃圾收集语言,他们的文档在这里说“从正确性的Angular 来看,你不需要知道变量被分配到哪里”。
如果我有下面的代码从一个通道读取,

for {
    select {
    case msg := <-stream.Messages():
    ...snip...

变量msg在case语句的范围内。

  • 如果它超出了case语句的作用域,会发生什么?由于这是在同一个本机函数中声明的,并且stream的大小可能是一个大字节片,变量将存储在堆或堆栈中,如果是堆,它将被垃圾收集,还是堆栈指针进入画面?
  • 由于这是在一个无限for循环中,并且stream的大小是一个大字节片,所以每次创建变量并分配内存都是一个开销,或者我应该提前声明变量,并在每次迭代中覆盖它,这样如果涉及垃圾收集,我不确定,我可能会减少垃圾?
  • 难道我就不应该为此烦恼吗?
yrwegjxp

yrwegjxp1#

难道我就不应该为此烦恼吗?
不知道
(And一旦它困扰你:profile.)

jchrr9hc

jchrr9hc2#

如果通道值类型是切片,则变量msg的值只是切片描述符,它很小(参见https://blog.golang.org/go-slices-usage-and-internals)。包含切片引用的数据的数组将在切片被放置到通道上之前被分配到其他位置。假设该值必须在分配它的函数返回后继续存在,它将在堆上。请注意,切片的内容实际上并没有被通道接收操作移动或复制。
一旦msg的值变得不可访问(由于变量超出范围或被分配了不同的值),假设没有其他对切片底层数组的引用,它将受到垃圾收集。
在不了解程序工作原理的情况下,很难说一定程度的优化是否有帮助。

相关问题