這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
寫個demo測試一下,channel中傳遞的是資料的拷貝,還是引用?
預期:傳遞的是參考型別
package mainimport ( "fmt")func main() { var sliceChan chan [2]map[string]int = make(chan [2]map[string]int, 2) //construct array m1 := map[string]int{ "rows":12, } m2 := map[string]int{ "columns":10, } bulk := [2]map[string]int{m1, m2} //directly read then sliceChan <- bulk e := <-sliceChan fmt.Println(e) //modify m2 m2["finish"] = 1 fmt.Println(e);}
最終輸出的結果,跟預想的一樣。列印的結果說明,e使用引用的是原資料的地址。
[map[rows:12] map[columns:10]][map[rows:12] map[columns:10 finish:1]]
修改chan資料類型,下面替換為依次替換為數組、slice、struct對象。
傳遞數群組類型
只需修改chan類型,其他不變。將chan類型修改為[2]int類型,其他不變。預期返回的應該是值得拷貝
func main() { var sliceChan chan [2]int = make(chan [2]int, 1) //construct array bulk := [2]int{1,2} //directly read then sliceChan <- bulk e := <-sliceChan fmt.Println(e) //modify m2 bulk[1] = 3 fmt.Println(e); fmt.Println(bulk)}
返回結果跟預期一致:
[1 2][1 2][1 3]
修改類型為slice
func main() { var sliceChan chan []int = make(chan []int, 1) //construct array bulk := []int{1,2} //directly read then sliceChan <- bulk e := <-sliceChan fmt.Println(e) //modify m2 bulk[1] = 3 fmt.Println(e); fmt.Println(bulk)}
跟預期一致,傳遞的跟map一樣,也是引用。返回的結果如下:
[1 2][1 3][1 3]
修改類型為struct
預期當struct傳遞實值型別的時候,傳遞的是值得拷貝;傳遞參考型別的時候,傳遞的是引用
func main() { type people struct { name string age int } var sliceChan chan people = make(chan people, 1) //construct array bulk := people{ "zhangshan", 28, } //directly read then sliceChan <- bulk e := <-sliceChan fmt.Println(e) //modify m2 bulk.name = "wangwu" fmt.Println(e); fmt.Println(bulk)}
上述使用的是值拷貝,結果也確實是這樣
{zhangshan 28}{zhangshan 28}{wangwu 28}
當修改成引用後,確實也是引用傳遞了。
Golang為什麼要這樣設計了?這樣設計有什麼好處?