L'éditeur php Yuzai révèle pour vous une question sur le découpage : pourquoi l'écriture dans le slice via les canaux et goroutine finit-elle par être vide ? Dans Go, les canaux et les goroutines sont des outils importants pour la programmation simultanée, mais dans certains cas, leur utilisation pour écrire des tranches peut avoir des résultats inattendus. Cet article expliquera en détail la cause de ce problème et proposera des solutions pour vous aider à mieux comprendre et gérer cette situation.
J'exécute cette fonction :
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) }
Mais au final, ma vertices
tranche est vide :
func doublecheckvertices(vertices []vertex) () { // here i notice that `vertices` slice is actually empty :( }
La fonction qui renvoie writer
est comme ceci :
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 }
Quelqu'un peut-il m'aider à comprendre pourquoi ma vertices
tranche finit vide ?
Le journal montre que vertices
切片实际上已填充。但由于某种原因,传递给doublecheckvertices
la tranche est effectivement remplie. Mais pour une raison quelconque, il est vide lorsqu'il est transmis à doublecheckvertices
.
vertices = append(vertices, a) // This Log shows the slice is actually filled out: fmt.Printf("vertices len() is %v\n", len(vertices))
Cela ressemble à "passer la tranche comme argument de fonction et modifier la tranche d'origine"
Si vous souhaitez que la goroutine modifie une tranche que vous avez créée en externe, vous avez besoin d'un pointeur vers la tranche :
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 }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!