I run this function:
func Run() () {
// This slice is going to be filled out by a channel and goroutine.
vertices := make([]Vertex, 0)
var wg sync.WaitGroup
// Obtain a writer to fill out the vertices.
writer := Writer(&wg, vertices)
// Run an arbitrary logic to send data to writer.
Logic(writer)
// Stop the writer reading on the channel.
close(writer)
// Wait for the write to complete.
wg.Wait()
// See if vertices slice is actually filled out.
DoublecheckVertices(vertices)
}
But eventually, my vertices
slice is empty:
func DoublecheckVertices(vertices []Vertex) () {
// Here I notice that `vertices` slice is actually empty :(
}
The function which returns the writer
is something like this:
func Writer(wg *sync.WaitGroup, vertices []Vertex) (chan<- []*Triangle3) {
// External code writes to this channel.
// This goroutine reads the channel and writes to vertices.
writer := make(chan []*Triangle3)
// Write by a goroutine.
wg.Add(1)
go func() {
defer wg.Done()
a := Vertex{}
// Read from the channel and write them to vertices.
for ts := range writer {
for _, t := range ts {
a.X = float32(t.V[0].X)
a.Y = float32(t.V[0].Y)
a.Z = float32(t.V[0].Z)
vertices = append(vertices, a)
}
}
}()
return writer
}
Can anybody help me with figuring out why my vertices
slice is eventually empty?
Logs
Logs indicate that the vertices
slice is actually filled out. But for some reason, it's empty when it's passed to DoublecheckVertices
.
vertices = append(vertices, a)
// This Log shows the slice is actually filled out:
fmt.Printf("vertices len() is %v\n", len(vertices))
CodePudding user response:
That seems similar to "Pass slice as function argument, and modify the original slice"
If you want your goroutine to modify the slice you created outside, you would need a pointer to that slice:
func Writer(wg *sync.WaitGroup, vertices *[]Vertex) (chan<- []*Triangle3) {
// External code writes to this channel.
// This goroutine reads the channel and writes to vertices.
writer := make(chan []*Triangle3)
// Write by a goroutine.
wg.Add(1)
go func() {
defer wg.Done()
a := Vertex{}
// Read from the channel and write them to vertices.
for ts := range writer {
for _, t := range ts {
a.X = float32(t.V[0].X)
a.Y = float32(t.V[0].Y)
a.Z = float32(t.V[0].Z)
*vertices = append(*vertices, a) <=====
}
}
}()
return writer
}