php-Editor Yuzai stellt Ihnen eine Frage zum Slicing: Warum ist das Schreiben in den Slice über Kanäle und Goroutine am Ende leer? In Go sind Kanäle und Goroutinen wichtige Werkzeuge für die gleichzeitige Programmierung, aber in manchen Fällen kann ihre Verwendung zum Schreiben von Slices zu unerwarteten Ergebnissen führen. In diesem Artikel wird die Ursache dieses Problems ausführlich erläutert und Lösungen bereitgestellt, die Ihnen helfen, diese Situation besser zu verstehen und damit umzugehen.
Ich führe diese Funktion aus:
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) }
Aber am Ende ist mein vertices
Stück leer:
func doublecheckvertices(vertices []vertex) () { // here i notice that `vertices` slice is actually empty :( }
Die Funktion, die writer
zurückgibt, sieht folgendermaßen aus:
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 }
Kann mir jemand helfen herauszufinden, warum mein vertices
-Slice leer bleibt?
Das Protokoll zeigt, dass vertices
切片实际上已填充。但由于某种原因,传递给doublecheckvertices
der Slice tatsächlich gefüllt ist. Aber aus irgendeinem Grund ist es leer, wenn es an doublecheckvertices
übergeben wird.
vertices = append(vertices, a) // This Log shows the slice is actually filled out: fmt.Printf("vertices len() is %v\n", len(vertices))
Das sieht ähnlich aus wie „den Slice als Funktionsargument übergeben und den ursprünglichen Slice ändern“
Wenn Sie möchten, dass die Goroutine ein extern erstelltes Slice ändert, benötigen Sie einen Zeiger auf das 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 }
Das obige ist der detaillierte Inhalt vonÜber Kanäle und Goroutinen in Slices schreiben: Warum Slices leer bleiben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!