新闻中心

如何在Golang中实现指针深拷贝

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

如何在golang中实现指针深拷贝

在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

使用序列化方式通用深拷贝

对于复杂嵌套结构,手动写太繁琐。可以利用序列化反序列化来实现深拷贝,例如使用 gobjson

短影AI 短影AI

长视频一键生成精彩短视频

短影AI 170 查看详情 短影AI
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使用终端命令确保文件无法被恢复  精准捕获:如何在页面中监听除特定元素外的所有点击事件  微信网页版官方快速登录入口 微信网页版网页版账号直达  菜鸟取件码是什么怎么查 最全查询渠道汇总 

搜索