具有命名返回值的Go函数内的数据竞争? 问题:

具有命名返回值的Go函数内的数据竞争? 问题:,go,Go,在返回新错误的同时,baz写入err之间的qux()以下代码中是否存在不明显的数据竞争?Go的内部处理是否可能将显式返回新变量视为对命名返回值的事实赋值,从而允许在此进行数据竞争 func-foo(baz-time.Duration)(bar*bar,err-error){ 完成:=make(chan结构{}) go func(){ bar,err=qux() 结束(完成) }() 挑选{ 案例答案 是的,命名返回函数中的显式返回将按照写入预初始化的命名结果 背景 如果您运行以下代码,您会注意到

在返回新错误的同时,
baz
写入
err
之间的
qux()
以下代码中是否存在不明显的数据竞争?Go的内部处理是否可能将显式返回新变量视为对命名返回值的事实赋值,从而允许在此进行数据竞争

func-foo(baz-time.Duration)(bar*bar,err-error){
完成:=make(chan结构{})
go func(){
bar,err=qux()
结束(完成)
}()
挑选{
案例答案
是的,命名返回函数中的显式返回将按照写入预初始化的命名结果

背景 如果您运行以下代码,您会注意到,即使在
foo()
中,在初始赋值之后,预初始化的
val
从未被直接操作,但它在返回
val2
后会更改内容

主程序包
进口(
“fmt”
“时间”
)
func main(){
val:=foo()
fmt.Printf(“Main:%+v\n”,val.Bar)//显式
时间。睡眠(2*时间。秒)
}
类型Foo struct{
棒串
}
func foo()(val*foo){
val=&Foo{Bar:“命名”}
go func(){
时间。睡眠(时间。秒)
fmt.Printf(“Goroutine:%+v\n”,val.Bar)//显式
}()
val2:=&Foo{Bar:“显式”}
返回值2
}
这是因为在Go中,零值返回参数在每个函数启动时都被初始化。然后在返回时,所有返回值都被分配给预初始化的参数。在我们的示例中,返回时
val2
被分配给
val
,然后由函数返回。这就打开了数据竞争的可能性,因为即使将值分配给
val2
它最终也会分配给
val


我唯一的借口是,截至撰写本文之时,该官员稍显不直观,因为它说命名结果已初始化并与未加修饰的回报挂钩,而未加修饰的回报错误地假定显式回报不挂钩。。功劳归于后面的乐于助人。

我不确定你的确切意思“时间竞赛漏洞”,但看起来确实存在数据竞赛。是否使用竞赛检测器对此进行了测试?这将更有帮助,因为它应该指出对值的读写冲突。还不清楚“命名参数”是什么意思,或者这对数据竞赛有什么影响。你能澄清这个问题吗?正如Jim所建议的,用竞赛检测器运行吗?我认为“命名返回值”是你想说的,而不是“命名参数”。感谢您的输入。让我澄清一下,命名返回值与Go own调用的命名返回参数完全相同,并且数据竞争/时间竞争通常可以互换使用,尽管如此,我将编辑此问题以减少混淆。运行数据竞争检测器是我调试此问题时做的第一件事,但它没有检测到在
fetchAndLearn
中比赛。整个问题不是关于发生了什么,而是为什么。我现在将编辑这个问题,使其更容易理解,而不必思考。
unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x40ebfa]

goroutine 7431988 [running]:
runtime.throw(0x1bcf57c, 0x5)
    /usr/local/go/src/runtime/panic.go:1116 +0x72 fp=0xc0026e8d38 sp=0xc0026e8d08 pc=0x43bef2
runtime.sigpanic()
    /usr/local/go/src/runtime/signal_unix.go:727 +0x405 fp=0xc0026e8d68 sp=0xc0026e8d38 pc=0x452805
runtime.getitab(0x195cae0, 0xe93824548b483024, 0x1, 0x7f7fc8037af8)
    /usr/local/go/src/runtime/iface.go:39 +0x3a fp=0xc0026e8db8 sp=0xc0026e8d68 pc=0x40ebfa
runtime.assertI2I2(0x195cae0, 0xdcd388, 0x0, 0x7f7fc8037af8, 0xc018808a20, 0xc012bbaa01)
    /usr/local/go/src/runtime/iface.go:472 +0x6a fp=0xc0026e8de8 sp=0xc0026e8db8 pc=0x41004a
errors.Is(0x1dd3f20, 0xc0120b6780, 0x1dd2a60, 0xc00003c1c0, 0xc019510c60)
    /usr/local/go/src/runtime/wrap.go:49 +0xd8 fp=0xc0026e8e50 sp=0xc0026e8de8 pc=0xaacbf8