Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
go中的并发和按值传递_Go_Concurrency - Fatal编程技术网

go中的并发和按值传递

go中的并发和按值传递,go,concurrency,Go,Concurrency,我在go中有一个代码片段: for _, u := range urls { done.Add(1) u2 := u go func() { defer done.Done() ConcurrentMutex(u2, fetcher, f) }() //go func(u string) { // defer done.Done() /

我在go中有一个代码片段:

for _, u := range urls {
        done.Add(1)
        u2 := u
        go func() {
            defer done.Done()
            ConcurrentMutex(u2, fetcher, f)
        }()
        //go func(u string) {
        //  defer done.Done()
        //  ConcurrentMutex(u, fetcher, f)
        //}(u)
    }

为了让
concurrentutex
看到不同的
u
值,需要使用中间变量
u2
或使用注释掉的代码。如果我只是做:

for _, u := range urls {
        done.Add(1)
        go func() {
            defer done.Done()
            ConcurrentMutex(u, fetcher, f)
        }()
    }

我不明白为什么这个行为会与注释掉的代码的行为不同。Go是通过值传递的,当我将
u
传递给
concurrentutex
时,它不应该只是复制当前
u
的值,从而对以后对
u
所做的更改免疫吗?

u
传递给
concurrentutex
的那一刻,它的副本将被创建并传递。但是,当goroutine传递
u
的值时,它可能与goroutine启动时处于活动状态的
u
值不同。也就是说,这种执行是可能的:for循环用
u
值启动goroutine,然后for循环用序列中的下一项覆盖
u
值,然后goroutine用新的
u
值调用
concurrentutex
,跳过上一个
u
值。

是,参数总是按值传递,但您不知道参数何时求值,因为它同时发生在循环中。对于如此短的循环,所有ConcurrentMutex调用都很可能(但不能保证!)在循环长时间结束后发生。谢谢,这很有意义。但是,对于注释掉的代码,这为什么不是一个问题呢?在注释掉的代码中,
u
的副本被传递给函数。即使for循环中的
u
in发生变化,函数中的副本也不会发生变化。如果将
&u
传递给获取指针的函数,则此操作将失败。