php小編魚仔為您揭示一個關於切片的問題:為什麼透過通道和 goroutine 寫入切片最終為空?在Go語言中,通道和 goroutine 是並發程式設計的重要工具,但在某些情況下,使用它們寫入切片可能會出現意外結果。本文將詳細解釋這個問題的原因,並提供解決方案,幫助您更好地理解和處理這種情況。
我執行這個函數:
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) }
但最終,我的 vertices
切片是空的:
func doublecheckvertices(vertices []vertex) () { // here i notice that `vertices` slice is actually empty :( }
傳回 writer
的函數是這樣的:
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 }
任何人都可以幫我弄清楚為什麼我的 vertices
切片最終是空的嗎?
日誌顯示 vertices
切片實際上已填入。但由於某種原因,傳遞給doublecheckvertices
時為空。
vertices = append(vertices, a) // This Log shows the slice is actually filled out: fmt.Printf("vertices len() is %v\n", len(vertices))
這看起來類似於「將切片作為函數參數傳遞,並修改原始切片」
如果您希望 goroutine 修改您在外部建立的切片,則需要一個指向該切片的指標:
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 }
以上是透過通道和 goroutine 寫入切片:為什麼切片最終為空的詳細內容。更多資訊請關注PHP中文網其他相關文章!