【发布时间】:2024-01-23 08:55:01
【问题描述】:
我最近一直在学习 go,并且对重新分配发生时切片的行为有疑问。假设我有一片指向结构的指针,例如:
var a []*A
如果我要将这个切片传递给另一个函数,我的理解是在内部这会按值传递切片头,它在单独的 goroutine 上运行并且只是从切片中读取,而启动 goroutine 的函数继续附加到切片,这是一个问题吗?例如:
package main
type A struct {
foo int
}
func main() {
a := make([]*A, 0, 100)
ch := make(chan int)
for i := 0; i < 100; i++ {
a = append(a, &A{i})
}
go read_slice(a, ch)
for i := 0; i < 100; i++ {
a = append(a, &A{i+100})
}
<-ch
}
func read_slice(a []*A, ch chan int) {
for i := range a {
fmt.Printf("%d ", a[i].foo)
}
ch <- 1
}
因此,据我了解,由于 read_slice() 函数在其自己的 goroutine 上运行并带有切片标头的副本,因此它具有指向当前支持数组的底层指针以及调用它时的大小,我通过它可以访问 foo 的。
但是,当另一个 goroutine 附加到 slice 时,它会在超出容量时触发重新分配。 go 运行时是否不会将内存释放给 read_slice() 中使用的旧后备数组,因为该函数中有对它的引用?
我尝试使用“go run -race slice.go”运行它,但没有报告任何内容,但我觉得我可能在这里做错了什么?任何指针将不胜感激。
谢谢!
【问题讨论】: