当前位置:网站首页>Golang 对分片 append 是否会共享数据
Golang 对分片 append 是否会共享数据
2022-04-23 14:11:00 【Mrpre】
Golang 对分片 append 是否会共享数据
Golang 官方对 slice 的说明见文章:https://blog.golang.org/slices-intro 大部分特别是前半部分,写的非常详细,但是最后关于append相关部分,就让人感觉浅尝辄止了。
首先,先写结论:append 返回的slice对象,有可能会共享入参slice的底层(意味着对返回对象slice的赋值会影响入参slice)也可能不共享入参slice的底层。
先给几个例子
例1:
package main
import (
"fmt"
)
func main() {
s := make([]int, 3)
s[1] = 1000
fmt.Println(len(s), cap(s), s)
}
打印出的结果就是3 3 [0 1000 0]
,这个毫无争议。
例2:
package main
import (
"fmt"
)
func main() {
s1 := make([]int, 3)
s2 := append(s1, 1000)//s1 追加 值1000,返回值是s2
fmt.Println("s2", len(s2), cap(s2), s2)
fmt.Println("s1", len(s1), cap(s1), s1)
fmt.Println("After modify s2")
s2[1] = 999//对s2赋值,看看是否对s1有影响
fmt.Println("s2", len(s2), cap(s2), s2)
fmt.Println("s1", len(s1), cap(s1), s1)
}
打印结果
s2 4 6 [0 0 0 1000]
s1 3 3 [0 0 0]
After modify s2
s2 4 6 [0 999 0 1000]
s1 3 3 [0 0 0]
似乎,我们对s2的赋值(s2[1] = 999)没有影响s1,所以,append返回的对象,就和是s1没任何关系了?NO,我们来看例3
例3:
package main
import (
"fmt"
)
func main() {
s1 := make([]int, 3)
s_slice := s[1:2]
s2 := append(s_slice, 1000)
fmt.Println("s2", len(s2), cap(s2), s2)
fmt.Println("s1", len(s1), cap(s1), s1)
fmt.Println("After modify s2")
s2[1] = 999
fmt.Println("s2", len(s2), cap(s2), s2)
fmt.Println("s1", len(s1), cap(s1), s1)
}
s2 2 2 [0 1000]
s1 3 3 [0 0 1000]
After modify s2
s2 2 2 [0 999]
s1 3 3 [0 0 999]
从结果来看,你看s1被同步修改了。例3 和 例2的唯一区别在于append的入参,s_slice和s1,这里 我们就要反过头来看看文章前面提到的官方文档:https://blog.golang.org/slices-intro 分片的属性包含3个(数组指针、cap、len),而例3中,s_slice和s1的区别就在于 他两 cap len不同(相关知识可以搜索其他文章或者直接看上面给的链接)。
所以,可以猜到,append的操作肯定是判断了 cap 或者len了。 cap 表示 了 slice的存储最大能力,len表示当前元素个数。
len(s1), cap(s1),都是3,表示 s1 容量是3,元素个数是3,即表示 s1满了,你在s1上操作append,那么必然需要新创建数组指针,即例2中,s2->数组指针 和 s1->数组指针 完全是独立的。这也就是为什么 append 入参 是 s1 时,对返回的s2的操作,根本不会影响s1。
回到 例3,入参 s_slice 的 cap 是 2,len 是1(因为s_slice 衍生自s1,s1容量是3,len是3,s_slice取[1:2],cap还空了一个),所以此时 s_slice 是有容量的。
对于有容量的slice,append操作,是在当前 指针数组后面插入值即可。这也就意味着,s2使用了s1的指针数组,修改s1会同步修改s1。
append实现的伪代码可以理解为
append(src, other) {
ret = src
//超过容量,就申请新的内存,否则返回对象的byte还是src的byte
if len(other) + src->len > src->cap {
byte = new(...);
copy(byte, src->byte)
ret->byte = byte//replaced by new buffer
} //else ret->byte == src->byte
copy(src->byte + src->len, other)
}
append居然还有两副面孔。
版权声明
本文为[Mrpre]所创,转载请带上原文链接,感谢
https://wonderful.blog.csdn.net/article/details/107486979
边栏推荐
- JS recursion (1)
- 线程间控制之CountDownLatch和CyclicBarrier使用介绍
- 容灾有疑问?点这里
- Thread group ThreadGroup uses introduction + custom thread factory class to implement threadfactory interface
- Some experience of using dialogfragment and anti stepping pit experience (getactivity and getdialog are empty, cancelable is invalid, etc.)
- 逻辑卷创建与扩容
- 金融行业云迁移实践 平安金融云整合HyperMotion云迁移解决方案,为金融行业客户提供迁移服务
- json date时间日期格式化
- ThreadGroup ThreadGroup implémente l'interface threadfactory en utilisant la classe Introduction + Custom thread Factory
- Gartner预测云迁移规模大幅增长;云迁移的优势是什么?
猜你喜欢
云迁移的六大场景
统信UOS卸载php7.2.24,安装php7.4.27 ;卸载再安装为PHP 7.2.34
Storage path of mod subscribed by starbound Creative Workshop at Star boundary
在Clion中给主函数传入外部参数
Processing MKDIR: unable to create directory 'AAA': read only file system
利用json-server在本地创建服务器请求
处理 mkdir:无法创建目录“aaa“:只读文件系统
Win10 comes with groove music, which can't play cue and ape files. It's a curvilinear way to save the country. It creates its own aimpack plug-in package, and aimp installs DSP plug-in
man man随记和crontab的@reboot用法
OpenStack如何跨版本升级
随机推荐
Wechat applet rotation map swiper
How to do a project easily
API Gateway/API 网关(三) - Kong的使用 - 限流rate limiting(redis)
政务云迁移实践 北明数科使用HyperMotion云迁移产品为某政府单位实施上云迁移项目,15天内完成近百套主机迁移
编译Openssl
Tongxin UOS uninstall php7 2.24, install php7 4.27 ; Uninstall and then install PHP 7.2.34
MySQL数据库讲解(十)
mysql查询库大小
Logback logger and root
Operation instructions of star boundary automatic text translator (advanced version)
MySQL-InnoDB-事务
微信小程序将原生请求通过es6的promise来进行优化
HyperMotion云迁移完成阿里云专有云产品生态集成认证
统信UOS PHP7.2.3升级至PHP7.2.24
JS parabola motion packaging method
rsync+inotify远程同步
Uni app message push
ThreadGroup ThreadGroup implémente l'interface threadfactory en utilisant la classe Introduction + Custom thread Factory
OpenSSH的升级、版本号的修改
Introduction to loan market quotation interest rate (LPR) and loan benchmark interest rate