Time won't go back I won't turn back.數組
時光不會倒着走,我也不會再回頭。數據結構
其實應該理解爲是slice的坑致使。 app
這個問題實際上是出如今引用類型( 此處是slice )上, 這個是 slice 的數據結構,它很簡單,一個指向真實 array 地址的指針 ptr ,slice 的長度 len 和容量 cap 。性能
結構圖解1指針
每次cap改變的時候指向array內存的指針都在變化, 在實際使用中,咱們最好事先預期好一個cap,這樣在使用append的時候能夠避免反覆從新分配內存複製以前的數據,減小沒必要要的性能消耗。code
如今上實例,來看看坑所在:協程
package main import "fmt" import "time" func main() { ch := make(chan []byte, 10) go func() { for { select { case data := <-ch: fmt.Println(string(data)) } } }() data := make([]byte, 0, 32) data = append(data, []byte("bbbbbbbbbb")...) ch <- data // fmt.Printf("%p\n", data) data = data[:0] // fmt.Printf("%p\n", data) data = append(data, []byte("aaa")...) ch <- data time.Sleep(time.Second * 5) }
預測的運行結果:進程
bbbbbbbbbb內存
aaastring
可是確定是有坑的:
前面新起了一個協程來等待通道接受信息, 主進程繼續執行, 當data第一次傳遞給了通道以後, (第二次append)馬上修改了data指向數組的值(aaabbbbbbb),要注意的地方還有data = data[:0], 因此通道第一次接收的值就已經改變了, 由於咱們傳遞的是引用,不是值類型。
若是在Append以前sleep, 那麼確定輸出的是bbbbbb 。
解決方案呢就是加鎖 或者新變量拷貝。