This is a creation in
Article, where the information may have evolved or changed.
Time won ' t go back I won ' t turn back.
Time will not go backwards, I will not look back.
In fact, this problem is in the reference type (here is slice), this is the slice data structure, it is very simple, a pointer to the real array address ptr, slice length len and capacity cap.
Structural Diagram 1
Each time the CAP changes, the pointer to the array memory is changing, and in practice we'd better anticipate a cap in advance, so that when using append, you can avoid repeatedly reallocating the data before the memory is copied, reducing unnecessary performance consumption.
Now on the example, take a look at where the pit is:
package mainimport "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 <- datatime.Sleep(time.Second * 5)}
Predicted run results:
bbbbbbbbbb
Aaa
But there must be a pit :
In front of a new process to wait for the channel to accept the information, the main processes continue to execute, when data is passed to the channel, the data is immediately modified to the value of the array (second append), so the first time the channel receives the value has changed, because we pass a reference, not a value type.
The solution is to lock or copy the new variable.