新闻中心
如何在Golang中实现指针深拷贝
深拷贝需复制指针指向的数据而非指针本身。当结构体含引用类型(如slice),直接赋值仅复制引用(浅拷贝),导致数据共享;修改一方会影响另一方。例如Person结构体的Tags字段为slice,p1与p2赋值后共用底层数组,更改p2.Tags会影响p1.Tags。解决方法有三:一是手动实现DeepCopy方法,递归复制每个字段,适用于简单结构;二是利用gob或json序列化再反序列化,实现通用深拷贝,但要求字段导出且不支持chan、func等类型;三是使用第三方库如mohae/deepcopy或jinzhu/copier,通过反射自动完成复制,适合复杂嵌套结构。核心是确保副本间无内存共享,保证数据独立性。

在Go语言中,指针本身只是一个地址,无法直接“深拷贝”,真正需要深拷贝的是指针指向的数据。如果结构体包含指针或引用类型(如 slice、map、chan 等),简单的赋值只会复制指针值(浅拷贝),多个变量会共享同一块内存。要实现真正的独立副本,必须递归地复制所有层级的数据。
理解浅拷贝与深拷贝
假设有一个结构体:
type Person struct {
Name string
Age int
Tags []string // slice 是引用类型
}
当执行如下操作:
p1 := Person{Name: "Alice", Age: 30, Tags: []string{"go", "dev"}}
p2 := p1 // 浅拷贝
p2.Tags[0] = "rust"
你会发现 p1.Tags[0] 也变成了 "rust",因为两个结构体共享同一个 slice 底层数据。这就是浅拷贝的问题。
手动实现深拷贝
最直接的方式是手动编写复制逻辑:
func (p *Person) DeepCopy() *Person {
if p == nil {
return nil
}
var tagsCopy []string
if p.Tags != nil {
tagsCopy = make([]string, len(p.Tags))
copy(tagsCopy, p.Tags)
}
return &Person{
Name: p.Name,
Age: p.Age,
Tags: tagsCopy,
}
}
使用方式:
p1 := &Person{Name: "Alice", Age: 30, Tags: []string{"go", "dev"}}
p2 := p1.DeepCopy()
p2.Tags[0] = "rust" // 不影响 p1
使用序列化方式通用深拷贝
对于复杂嵌套结构,手动写太繁琐。可以利用序列化反序列化来实现深拷贝,例如使用 gob 或 json:
短影AI
长视频一键生成精彩短视频
170
查看详情
import "bytes"
import "encoding/gob"
func DeepCopy(src, dst interface{}) error {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
dec := gob.NewDecoder(&buf)
err := enc.Encode(src)
if err != nil {
return err
}
return dec.Decode(dst)
}
使用示例:
p1 := &Person{Name: "Alice", Age: 30, Tags: []string{"go"}}
var p2 Person
err := DeepCopy(p1, &p2)
if err != nil {
log.Fatal(err)
}
// p2 是
p1 的深拷贝
注意:gob 要求字段必须可导出(大写开头),且不支持某些类型(如 chan、func)。
第三方库推荐
可以使用成熟的库简化操作:
- github.com/mohae/deepcopy:纯 Go 实现,通过反射复制基本和复合类型。
- github.com/jinzhu/copier:功能更强,支持结构体间字段拷贝,甚至可以处理不同类型但字段名相同的结构体。
示例(使用 deepcopy):
import "github.com/mohae/deepcopy" p2 := deepcopy.Copy(p1).(*Person)
基本上就这些。选择哪种方式取决于你的场景:简单结构用手动,通用需求用序列化或第三方库。关键是理解深拷贝的本质——创建完全独立的数据副本。
以上就是如何在Golang中实现指针深拷贝的详细内容,更多请关注其它相关文章!
# 不支持
# 辽宁营销网站建设流程
# 井冈山网站推广宣传海报
# 合作网站建设开发
# 平顶山网站seo优化收费标准
# 如何搜索网站关键词排名
# seo店
# 外贸营销网站推广文案
# seo app176 vip
# 日照网站建设做的好
# 广汉pc网站建设
# 多个
# 的是
# 如何在
# go
# 自定义
# 第三方
# 序列化
# 死锁
# 递归
# 解决方法
# go语言
# golang
# github
# json
# git
# js
# 指针深拷贝
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
消息称三星明年 2 月正式发布 HBM4,与 SK 海力士同台竞技
高德地图怎么看全景照片_高德地图全景照片浏览教程
J*aScript DOM操作:高效清空列表元素的策略与实践
Excel Power Pivot如何处理XML数据源 构建高级数据模型
sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤
在J*a中如何使用Stream.map转换元素_Stream映射操作解析
如何在离线环境中使用Composer_Composer离线安装依赖包的技巧与策略
python3时间如何用calendar输出?
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
淘宝网网页版登录入口 淘宝官方网页版快捷登录
怎样使用“本地安全策略”提升Windows安全性_Secpol.msc配置指南【高手】
Go RPC HTTP服务正确实现与常见陷阱解析
Python异步编程实践:使用Binance API构建实时交易数据流
Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】
Win10自动更新怎么关闭 Win10永久关闭系统更新的两种方法【终极版】
outlook中文官网入口地址 outlook官方中文版直达首页链接
C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略
《刺客信条:影》PS5 Pro和Switch 2画面对比
58动漫网在线官方网 58动漫网正版动漫入口网址
J*aScript中针对特定容器内图片动画的实现教程
创客贴用户入口官网登录 创客贴网页版电脑版系统
拼多多赚钱渠道_拼多多收益来源
Composer的 "check-platform-reqs" 命令有什么用_在部署前检查生产环境是否满足Composer依赖需求
2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享
PDF怎么合并PDF并保持格式_PDF合并文件保持排版教程
mysql如何设置表访问权限_mysql表访问权限配置
优化大型XML文件解析:基于Python流式处理的内存高效方案
windows10怎么关闭系统提示音_windows10彻底静音设置方法
QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用
Go语言HTML解析:利用Goquery精准获取指定元素内容
J*a编写用户注册与登录功能_掌握字符串与验证逻辑
在J*a中如何使用Exception包装底层异常_异常包装与信息传递方法说明
天猫2025双十一0点秒杀攻略 天猫爆款抢购时间
poki网页游戏推荐_poki免费游戏平台入口
在J*aScript中复现SciPy的B样条拟合与求值:关键考量
如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流
在命令行怎么运行html项目_命令行运行html项目方法【教程】
优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题
解决Python logging 中 datefmt 导致时间戳固定不变的问题
2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析
Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换
J*aScript中高效管理与清空动态列表:避免循环陷阱
蛙漫画网页版全站入口 蛙漫热门作品免费浏览
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
C++如何操作大型数据集_使用C++流式处理(Streaming)技术避免一次性加载大文件
MongoDB Aggregation:在嵌套对象数组中精确匹配ObjectId
MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复
精准捕获:如何在页面中监听除特定元素外的所有点击事件
微信网页版官方快速登录入口 微信网页版网页版账号直达
菜鸟取件码是什么怎么查 最全查询渠道汇总


2025-11-01
浏览次数:次
返回列表
p1 的深拷贝