寫個demo測試一下,channel中傳遞的是資料的拷貝,還是引用?
預期:傳遞的是引用型別
package main
import (
"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為什麼要這樣設計了?這樣設計有什麼好處?