golang 不寻常的 Go 构造:创建可重用的名称:名称:= 名称……某事

我在某处看到了这个构造,用于在向函数发送数据时重用“名称”。

我正在使用一个数据库,需要发送大量要处理的“命名”缓冲区。这个结构看起来很完美,但我无法工作,也不记得我在哪里看到过它的讨论。

任何帮助,将不胜感激。

文本的要点是,每次使用此结构时,名称都会反复使用,但每个实例实际上都将拥有它自己的集合。

我只记得它是 name := name ..then 的东西。我在这里迷路了。


jeck猫
浏览 187回答 2
2回答

慕村225694

您肯定是指创建循环变量的副本。通常,在此代码中:for i := 0; i < 100; i++ {&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; }}i将在所有 goroutines 中引用循环变量,所以如果 goroutines 产生,然后循环在它们调用之前继续运行fmt.Println(i),i当它们调用它时将与它们从循环中产生时不同。正如你提到的,解决这个问题的一种方法是:for i := 0; i < 100; i++ {&nbsp; &nbsp; i := i&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; }}添加的行i := i引入了一个名为 的局部变量i,并将其设置为等于循环变量i。这是两个不同的变量。你还不如说j := i然后用j。我倾向于认为使用i := i更令人困惑,但有些人更喜欢它。在任何情况下,鉴于它是一个局部变量,每个循环都有一个不同的实例,这意味着每个 goroutine 都会看到它自己的唯一实例,不会被更改。虽然这个习语可以在Effective Go 中找到(在页面上搜索“req := req”),但让我澄清一些事情:这是令人困惑的,应该避免。我不知道为什么 Go 作者认为引入这个习语是个好主意,在我看来,应该避免。为什么?因为有一种更简洁的方法可以完成更容易理解的相同事情:for i := 0; i < 100; i++ {&nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(i)&nbsp; &nbsp; }(i)}在这个版本中,匿名函数接受一个整数参数,当它在 goroutine 中产生时,循环变量i作为该参数传递。人们对这些语义有了更扎实的理解,因此更容易看到它的作用并理解它为什么起作用。如果这仍然令人困惑,我建议更改参数名称:for i := 0; i < 100; i++ {&nbsp; &nbsp; go func(j int) {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(j)&nbsp; &nbsp; }(i)}我认为这两种方法更容易理解,应该使用而不是您提到的示例。

素胚勾勒不出你

你的意思是这样的构造:func foo() {&nbsp; &nbsp; var bar // some variable&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; bar := bar // copy bar into inner scope&nbsp; &nbsp; }()}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go