1、channel 先看以下代码:
package mainimport "fmt"func main() {
ch1 := make(chan int, 3)
ch2 := ch1
ch1 <- 123
ch2 <- 456
fmt.Println(ch1, ch2)//输出地址是否一样?TODO:打印结果是?
fmt.Println(<-ch2, <-ch1) // ch2中的数据是:456; ch1中的数据是123;TODO:打印结果是?
}
输出结果:
文章图片
代码分析:
在以上代码中,新定义的变量ch2:=ch1 ;ch2是地址引用,ch1,ch2地址指向的是同一块数据,ch1、ch2都可以改变数据。
2、slice 看看以下代码:
package mainimport "fmt"func main() {
s := make([]int, 3)
s1 := s
s2 := s
s[0] = 123
s1[1] = 456
s2[2] = 789
fmt.Println("原始切片:", s)
fmt.Println("赋值切片:", s1)
fmt.Println("赋值切片:", s2)
fmt.Println("切片的长度、容量为:", len(s), cap(s))
fmt.Printf("追加之前的地址:s:%p ;
s1:%p;
s2:%p\n",s,s1,s2)
fmt.Println("====执行append操作====")
s2 = append(s2, 123)
fmt.Printf("追加之后的地址:s:%p ;
s1:%p;
s2:%p\n",s,s1,s2)
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
}
输出结果:
文章图片
代码分析:起初,s,s1,s2都指向同一块数据。所以任意一个变量修改了该块数据,其他变量查到的都是修改之后的数据。
【Go语言(Golang)地址引用避坑】指向:
s2 = append(s2, 123),会在末尾追加一个元素,由于现有s2的
cap(s)=3, len(s)=3;
在追加数据时,容量已经不够,会开辟新的内存,将现有数据s2拷贝,形成新的s2。当然在容量足够的情况下,不会开辟新的内存空间。
再来看以下代码:(容量大于append的数据数量)
package mainimport "fmt"func main() {
s := make([]int, 3,6)
s1 := s
s2 := s
s[0] = 123
s1[1] = 456
s2[2] = 789
fmt.Println("原始切片:", s)
fmt.Println("赋值切片:", s1)
fmt.Println("赋值切片:", s2)
fmt.Println("切片的长度、容量为:", len(s), cap(s))
fmt.Printf("追加之前的地址:s:%p ;
s1:%p;
s2:%p\n",s,s1,s2)
fmt.Println("====执行append操作====")
s2 = append(s2, 123)
fmt.Printf("追加之后的地址:s:%p ;
s1:%p;
s2:%p\n",s,s1,s2)
s[0]=888 // TODO:会修改s1、s2吗
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
}
输出效果:
文章图片
在以上代码中添加内容:
package mainimport "fmt"func main() {
s := make([]int, 3,6)
s1 := s
s2 := s
s[0] = 123
s1[1] = 456
s2[2] = 789
fmt.Println("原始切片:", s)
fmt.Println("赋值切片:", s1)
fmt.Println("赋值切片:", s2)
fmt.Println("切片的长度、容量为:", len(s), cap(s))
fmt.Printf("追加之前的地址:s:%p ;
s1:%p;
s2:%p\n",s,s1,s2)
fmt.Println("====执行append操作====")
s2 = append(s2, 123)
fmt.Printf("追加之后的地址:s:%p ;
s1:%p;
s2:%p\n",s,s1,s2)
s[0]=888 // TODO:会修改s1、s2吗
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
fmt.Println("执行以下操作,输出结果又是什么呢?")
s = append(s, 666)
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
}
文章图片
特别说明:Go语言为了节省内存空间,对于切片、map、channel、指针等地址引用的变量,会操作同一块地址对应的数据,在操作时也特别留意。
推荐阅读
- 【golang】leetcode中级-字母异位词分组&无重复字符的最长子串
- 彻底理解Golang Map
- kratos线上开源年会它来啦~
- 深入浅出 Golang 资源嵌入方案(go-bindata篇)
- 深入浅出 Golang 资源嵌入方案(前篇)
- golang 经典案例总结
- Go实战 | 基于有向无环图的并发执行流的实现
- Golang 数组和切片
- Go JSON编码与解码()
- golang map基础知识