写个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为什么要这样设计了?这样设计有什么好处?