面试题答案
一键面试- 问题分析:
- 在这段代码中,
for
循环启动了5个goroutine,这些goroutine共享变量i
。由于goroutine是并发执行的,在for
循环结束后,i
的值已经变为5,当goroutine执行data = append(data, i)
时,它们追加到data
切片中的值都是5,而不是预期的0到4。
- 在这段代码中,
- 正确实现:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
var data []int
for i := 0; i < 5; i++ {
wg.Add(1)
go func(j int) {
defer wg.Done()
data = append(data, j)
}(i)
}
wg.Wait()
fmt.Println(data)
}
- 原理说明:
- 通过在闭包函数的参数列表中传入
i
,并将这个传入的参数命名为j
(这里j
可以是任意合法变量名),每个goroutine就有了自己独立的j
变量,其值是在goroutine启动时i
的值。这样,每个goroutine在执行data = append(data, j)
时,就会将正确的值追加到data
切片中,实现了将0到4添加到data
切片的目的。这是因为每次调用闭包函数时,i
的值作为参数传递给闭包,在闭包内部形成了独立的变量,避免了所有goroutine共享同一个i
变量带来的问题。
- 通过在闭包函数的参数列表中传入