golang 对slice的深拷贝 copy
你看到的这个文章来自于http://www.cnblogs.com/ayanmw
测试 slice的地址 copy的时候 发现有问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package main import "fmt" func main() { nums:=[]int{1,2,3,4,5} fmt.Println( " len cap address" ) fmt.Print( "111---" ,len(nums),cap(nums)) fmt.Printf( " %p\n" ,nums) //0xc4200181e0 a:=nums[:3] fmt.Print( "222---" ,len(a),cap(a)) fmt.Printf( " %p\n" ,a) //0xc4200181e0 一样 //output: 222--- 3 5 b:=nums[:3:3] //第二个冒号 设置cap的 n:=copy(b,nums[:3:3]) //第二个冒号 设置cap的 fmt.Print( "333---" ,len(b),cap(b)) fmt.Printf( " %p\n" ,b) //0xc4200181e0 一样 //output: 333--- 3 3 fmt.Println(n,b) nums[0]=55 fmt.Println(nums,a,b) } |
发现 nums[0]修改了数据后,其他全部都改变了,并且地址都一样,想了想 到底哪里出了问题呢? 是 copy 的问题?
len cap address
111---5 5 0xc4200181e0
222---3 5 0xc4200181e0
333---3 3 0xc4200181e0
3 [1 2 3]
[55 2 3 4 5] [55 2 3] [55 2 3]
琢磨了一下,发现 原来是copy前的对象 没有分配内存,使用了一样的内存地址导致的,把上文的
1 | b:=nums[:3:3] //第二个冒号 设置cap的 |
修改为:
1 | var b =make([]int,len(nums[:3:3])) |
再进行copy 结果就如语气了,b的值不会被修改了。
len cap address
111---5 5 0xc4200181e0
222---3 5 0xc4200181e0
333---3 3 0xc42000a400
3 [1 2 3]
[55 2 3 4 5] [55 2 3] [1 2 3]
其实研究明白了,都是小问题;
golang深拷贝任意结构代码:
```
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Clone 完整复制数据 func Clone(a, b interface {}) error { buff := new(bytes.Buffer) enc := gob.NewEncoder(buff) dec := gob.NewDecoder(buff) if err := enc.Encode(a); err != nil { return err } if err := dec.Decode(b); err != nil { return err } return nil } |
参考文档:
https://golang.google.cn/ref/spec#Appending_and_copying_slices
转载请注明出处:http://www.cnblogs.com/ayanmw 我会很高兴的!
------------------------------------------------------------------------------------------------
一定要专业!本博客定位于 ,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。. linux,总之后台开发多一点。以后也愿意学习 cocos2d-x 游戏客户端的开发。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2012-03-28 少壮不努力,老大写程序(kobewry) 经典话语啊
2012-03-28 Socket之模型
2012-03-28 转:从问题看本质:socket到底是什么? .
2012-03-28 转:IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇) .
2012-03-28 linux之拷贝文件/备份文件;按照原来的权限和日期拷贝.