内容简介:golang 的slice是一个指向底层的数组的指针结构体。 这个结构体有三个属性,1.指向数组指针,2.len: slice中元素的数量 3.cap:slice占用内存数量。 只有深刻理解这三个属性才能在使用slice中不至于犯错。多个slice之间可以共享底层的数据,并且引用的数组部分区间可能重叠以上是golang 圣经中的一句话。深刻理解这句话对于日程编程非常有意义。
slice 三个属性
golang 的slice是一个指向底层的数组的指针结构体。 这个结构体有三个属性,1.指向数组指针,2.len: slice中元素的数量 3.cap:slice占用内存数量。 只有深刻理解这三个属性才能在使用slice中不至于犯错。
正确理解变量和共享
多个slice之间可以共享底层的数据,并且引用的数组部分区间可能重叠
以上是golang 圣经中的一句话。深刻理解这句话对于日程编程非常有意义。
1.什么时候共享数据会被其他变量修改
func f1() { a1 := []int{1,2,3,4,5,6} a2 := a1 a3 := a1[1:3] a1[1] = 999 fmt.Println("a1=",a1,"a2=",a2,"a3=",a3) }
运行结果
a1= [1 999 3 4 5 6] a2= [1 999 3 4 5 6] a3= [999 3] Process finished with exit code 0
我们清楚的看到了数据共享,此时修改了a1 ,两位两个变量都被修改
什么时候不会修改
func f2() { a1 := []int{1,2,3,4,5,6} a2 := a1 a3 := a1[1:3] a2 = append(a2,888) a1[1] = 999 fmt.Println("a1=",a1,"a2=",a2,"a3=",a3) }
运行结果
a1= [1 999 3 4 5 6] a2= [1 2 3 4 5 6 888] a3= [999 3] Process finished with exit code 0
可以虽然a1被修改,a2并没有修改。我们知道append函数会面临内存的重新分配。所以等a2进行append的时候,会重新申请内存空间,将原有数组拷贝然后增加如新值。也就是当append操作的时候,此时a2 不在和a1 共享内存了。所以后续对a1的操作是不会影响到a2.
3.所有的append操作都会隔断内存共享?
func f3() { a1 := []int{1,2,3,4,5,6} a2 := a1 a3 := a1[1:3] a2 = append(a2,888) a3 = append(a3,777) a1[1] = 999 fmt.Println("a1=",a1,"a2=",a2,"a3=",a3) }
运行结果
a1= [1 999 3 777 5 6] a2= [1 2 3 4 5 6 888] a3= [999 3 777] Process finished with exit code 0
这次a3 是对a1进行切片操作赋值的新变量。此时对a3进行append操作,我们发现a1的值同步被修改了。所以此时a3 和a1 仍然是共享内存,append并没有申请新的内存空间而是继续在a3的数据末尾写入,这样对于a1 是覆盖了原有值。
问题本质是
a1= [1 999 3 777 5 6] cap(a1) = 6 a2= [1 2 3 4 5 6 888] cap(a2) = 12 a3= [999 3 777] cap(a3) = 5
重新运行后将三个变量cap值打印为以上输出。
问题的本质是len 和cap 的值。 在slice中,当len小于cap 的值的时候, 进行append 操作是不会造成内存的重新分配。a3 是从a1切片操作而来,我们看到a3 初始化的len =2 ,cap =5.所以在append中不会引起内存重新分配,go 运行时会继续将数据依次写入。这样就修改了a3 和a1共享的内存空间。 对于a2,在初始化的时候len =cap =6. 在append操作的时候就会重新申请空间,go会分配当前空间 * 2 的内存。所以append后的cap就是12 如上。
总结
在对slice 复制的时候,如果面临多个变量同时指向一个数组的时候,一定要考虑到数据的共享和内存的重新分配。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 你真的理解主从复制吗?
- MongoDB复制选举原理及复制集管理
- MySQL组复制MGR(二)-- 组复制搭建
- Redis系列(四):Redis的复制机制(主从复制)
- JavaScript中对象的浅复制和深复制 原 荐
- [跨地域复制系列](二) Apache Pulsar 的跨地域复制实践
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Machine Learning
Kevin Murphy / The MIT Press / 2012-9-18 / USD 90.00
Today's Web-enabled deluge of electronic data calls for automated methods of data analysis. Machine learning provides these, developing methods that can automatically detect patterns in data and then ......一起来看看 《Machine Learning》 这本书的介绍吧!