新闻中心
如何在Golang中理解值拷贝与指针传递
Go中所有参数传递均为值拷贝,拷贝内容可能是数据本身或指针地址。1. 值拷贝:传基本类型、结构体时复制副本,函数内修改不影响原变量;2. 指针传递:拷贝的是地址,通过指针可修改原始数据;3. 特殊类型如slice、map、channel底层含指针,传递时拷贝的是指向底层数组的指针结构,故能间接修改数据,但重新赋值不影响外部;4. 选择依据:是否需修改原数据、数据大小、方法集一致性与nil安全性。核心是理解拷贝的是值还是指针。

在Go语言中,理解值拷贝与指针传递对编写高效、正确的程序至关重要。很多人刚接触Go时会对函数参数的传递方式产生误解,认为像切片或map是“引用传递”,其实Go中所有参数传递都是值拷贝,只是有时拷贝的是指针而已。
值拷贝:传递的是数据的副本
当一个变量以值的方式传入函数时,Go会创建该变量的一个副本。函数内部对参数的修改不会影响原始变量。
基本类型如 int、float、bool、string 以及结构体默认都是值拷贝:
type Person struct {
Name string
Age int
}
func modifyPerson(p Person) {
p.Name = "Alice"
p.Age = 30
}
func main() {
person := Person{Name: "Bob", Age: 25}
modifyPerson(person)
fmt.Println(person) // 输出 {Bob 25},原值未变
}
上面的例子中,modifyPerson 接收的是 person 的一份拷贝,内部修改不影响原始结构体。
指针传递:拷贝的是地址
要让函数能修改原始变量,需要传递变量的地址(即指针)。虽然这仍是“值拷贝”——拷贝的是指针的值,但由于指针指向同一块内存,因此可以通过它修改原数据。
func modifyPersonPtr(p *Person) {
p.Name = "Alice"
p.Age = 30
}
func main() {
person := Person{Name: "Bob", Age: 25}
modifyPersonPtr(&person)
fmt.Println(person) // 输出 {Alice 30},原值被修改
}
这里传递的是 &person,即 person 的地址。函数接收 *Person 类型,通过指针访问并修改原始结构体。
特殊类型的行为:slice、map、channel
虽然 slice、map 和 channel 不是基本类型,但它们底层由指针封装。当你传递这些类型时,拷贝的是包含指针的结构体(如 slice header),所以它们能“间接”修改底层数组或数据结构。
func modifySlice(s []int) {
s[0] = 999
}
func main() {
data := []int{1, 2, 3}
modifySlice(data)
fmt.Println(data) // 输出 [999 2 3]
}
尽管是值拷贝,但拷贝的 slice 仍指向相同的底层数组,因此修改生效。但若在函数内重新分配 slice,外部不会感知:
func reassignSlice(s []int) {
s = append(s, 4, 5, 6) // 可能触发扩容,指向新数组
}
// 调用后 data 长度仍为3,不受影响
如何选择:值还是指针?
决定使用值还是指针作为参数类型,主要考虑以下几点:
- 是否需要修改原数据:需要修改就用指针
- 数据大小:大结构体拷贝成本高,建议传指针
- 一致性:如果方法集中有指针接收者,其他方法也建议用指针,避免混淆
- nil 安全性:值接收者不会因 nil 指针而 panic,指针接收者需注意判空
基本上就这些。记住一句话:Go只有值拷贝,指针传递只是拷贝了地址。关键在于理解拷贝的内容是什么——是数据本身,还是指向数据的指针。
以上就是如何在Golang中理解值拷贝与指针传递的详细内容,更多请关注其它相关文章!
# 当你
# 如何做游戏推广营销号
# 新安县营销型网站建设
# 婚纱摄影全网推广营销
# 高要网站优化软件
# 安徽热点关键词排名
# 随州seo推广策划招聘
# 东阳seo全网营销价格
# 深圳外包营销推广多少钱
# seo网站优化多少钱一年合适
# 广东推广营销参考价格
# 相关文章
# 均为
# go
# 很多人
# 原值
# 移除
# 都是
# 数据结构
# 如何在
# 的是
# ai
# app
# go语言
# golang
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
邮政快递包裹最新位置 邮政快递实时追踪入口
win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】
J*aScript数组对象转换:按指定键分组与值收集
微信网页版登录教程_微信网页版登录入口在哪
如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension
Yandex搜索引擎一键访问入口_俄罗斯Yandex官网免登录
顺丰快递查单号物流信息 顺丰快递小程序查询入口
J*aScript类型检查_j*ascript代码规范
支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样
响应式容器内容自动缩放与宽高比维持教程
包子漫画官方网站在线链接-包子漫画在线阅读平台主页地址
outlook中文官网入口地址 outlook官方中文版直达首页链接
《噬血代码2》新预告片发布 展示游戏剧情
AO3官网镜像链接 Archive of Our Own同人文在线浏览
邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧
PHP中获取MongoDB服务器运行时间(Uptime)的专业指南
怎么去除衣服上的口红印_生活小妙招教你用酒精轻松擦除
QQ邮箱网页版入口页面 QQ邮箱在线登录入口官网
Go语言中动态执行代码字符串的策略与实践
UC浏览器如何安装插件 UC浏览器添加扩展程序详细教程【进阶】
提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案
在Go开发中优雅管理ListenAndServe进程:GoSublime集成方案
MAC如何将整个网页截长图_MAC使用Safari的导出为PDF或第三方工具
Discord Slash 命令响应超时问题的异步解决方案
在WordPress中通过REST API获取BasicAuth保护的远程文章
快手赚钱渠道_快手收益来源
c++如何使用std::memory_order控制原子操作顺序_c++ C++11内存模型详解
葱吃多了会怎样 葱吃多了会伤胃吗
怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】
UC浏览器网页版登录入口官网 电脑版网址入口
age动漫网站入口 age动漫官网直接访问入口
精准捕获:如何在页面中监听除特定元素外的所有点击事件
韩小圈电脑版在线入口_网页版免费登录地址
Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏
4399体育竞技小游戏_4399小游戏赛事入口
在J*a项目里如何构建对象之间的契约_接口约束的实际落地
Go语言中对Map值调用带指针接收者方法:原理与最佳实践
php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】
品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程
淘宝网网页版登录入口 淘宝官方网页版快捷登录
如何在复杂的电商平台中优雅地管理共享资源并确保正确重定向,使用spryker-shop/resource-share-page模块助你一臂之力
Django模型中自动计算可用余额的实现方法
Android Studio计算器C键功能异常排查与修复教程
mcjs网页版在线存档 mcjs云存档登录入口
腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程
外媒分析《GTA6》定价:卖100美元可以但真没必要!
lar*el怎么安全地存储和获取配置文件中的敏感信息_lar*el敏感信息安全存储方法
PHP表单数据传递:如何通过隐藏输入字段获取动态ID
抓大鹅无需下载版 抓大鹅秒玩版入口
C++ map遍历方法大全_C++ map迭代器使用总结


2025-11-04
浏览次数:次
返回列表
data := []int{1, 2, 3}
modifySlice(data)
fmt.Println(data) // 输出 [999 2 3]
}