Go语言地址引用的问题解决
1、channel
先看以下代码:
package main
import "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 main
import "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都指向同一块数据。所以任意一个变量修改了该块数据,其他变量查到的都是修改之后的数据。
指向:
s2 = append(s2, 123),会在末尾追加一个元素,由于现有s2的
cap(s)=3, len(s)=3;
在追加数据时,容量已经不够,会开辟新的内存,将现有数据s2拷贝,形成新的s2。当然在容量足够的情况下,不会开辟新的内存空间。
再来看以下代码:(容量大于append的数据数量)
package main
import "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 main
import "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、指针等地址引用的变量,会操作同一块地址对应的数据,在操作时也特别留意。
到此这篇关于Go语言地址引用的问题解决的文章就介绍到这了,更多相关Go语言地址引用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
go中Excelize处理excel表实现带数据校验的文件导出
本文主要介绍了go中Excelize处理excel表实现带数据校验的文件导出,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-06-06
golang如何通过viper读取config.yaml文件
这篇文章主要介绍了golang通过viper读取config.yaml文件,围绕golang读取config.yaml文件的相关资料展开详细内容,需要的小伙伴可以参考一下2022-03-03


最新评论