1 回答
TA贡献1798条经验 获得超3个赞
由于两个(实际上是三个)原因,您的代码无法正常工作:
append
达到容量后立即返回一个新切片。因此,赋值 inappendInt
将什么都不做。appendInt
同时运行,因此:只要
appendInt
没有消息main
说它完成了,main
不知道什么时候intSlice
有你想要的所有值。你必须等待所有 goroutines 在结束时返回
main
问题一:修改函数中的切片
您可能知道在 Go 中传递给函数的每个值都会被复制。引用值(例如切片)也被复制,但在内部具有指向原始内存位置的指针。这意味着您可以在函数中修改切片的元素。你不能做的是用一个新的切片重新分配这个值,因为内部指针会指向不同的地方。你需要指针。示例(播放):
func modify(s *[]int) {
for i:=0; i < 10; i++ {
*s = append(*s, i)
}
}
func main() {
s := []int{1,2,3}
modify(&s)
fmt.Println(s)
}
问题 2:同步 goroutines
要等待启动的 goroutine,您可以使用sync.WaitGroup. 示例(播放):
func modify(wg *sync.WaitGroup, s *[]int) {
defer wg.Done()
for i:=0; i < 10; i++ {
*s = append(*s, i)
}
}
func main() {
wg := &sync.WaitGroup{}
s := []int{1,2,3}
wg.Add(1)
go modify(wg, &s)
wg.Wait()
fmt.Println(s)
}
上面的示例等待(使用wg.Wait()
)modify
完成(完成时modify
调用wg.Done()
)。如果您删除wg.Wait()
呼叫,您将看到为什么不同步是一个问题。输出比较:
与
wg.Wait()
:[1 2 3 0 1 2 3 4 5 6 7 8 9]
没有
wg.Wait()
:[1 2 3]
main goroutine早于goroutine返回,modify
这就是为什么你永远不会看到修改后的结果。因此同步是绝对必要的。
传达新切片的一种好方法是使用通道。您不需要使用指针,并且可以进行同步。示例(播放):
func modify(res chan []int) {
s := []int{}
for i:=0; i < 10; i++ {
s = append(s, i)
}
res <- s
}
func main() {
c := make(chan []int)
go modify(c)
s := <-c
fmt.Println(s)
}
- 1 回答
- 0 关注
- 184 浏览
添加回答
举报