0

0

为什么Go值类型在传参时会发生拷贝_Go Value参数拷贝机制解析

P粉602998670

P粉602998670

发布时间:2025-12-25 14:30:02

|

385人浏览过

|

来源于php中文网

原创

Go中所有函数传参均为值拷贝,值类型(如int、string、struct)复制全部数据,结构体含指针时仅复制指针值而非其所指内容,故仍属值类型;纯值类型完全独立,含引用字段的类型拷贝后可能共享底层数据。

为什么go值类型在传参时会发生拷贝_go value参数拷贝机制解析

Go 中所有函数传参都是值拷贝,值类型(如 intstringstruct[3]int 等)也不例外——每次调用函数时,系统会把实参的完整数据复制一份,放进形参变量里。这个副本和原始变量在内存中完全独立,互不影响。

值类型拷贝的本质是“数据搬家”

值类型直接持有数据本身,不依赖外部存储。比如:

  • a := 42 → 内存中存的就是数字 42
  • u := User{Name: "Alice", Age: 30} → 整个结构体字段内容都连续存放在一块内存里

当它们被传入函数,Go 就把这一整块数据原样复制过去。哪怕结构体有 100 个字段,只要没含指针或引用类型,拷贝的就是全部字段的值。

拷贝行为可验证:地址完全不同

通过取地址能直观看到拷贝发生:

  • 主函数里 &myStruct 和函数内 &p 打印出的地址一定不同
  • 哪怕结构体里有指针字段,struct 本体仍是值类型,整个结构体(含指针字段的值)被复制,但指针字段指向的底层数据不会被复制

也就是说:结构体本身是副本,但它内部的指针仍可能指向同一片堆内存——这属于浅拷贝范畴,不是值类型“失效”,而是它按规则忠实地拷贝了自己包含的所有内容(包括指针值)。

为什么设计成这样?安全与确定性优先

值拷贝让函数边界清晰:

AILOGO
AILOGO

LOGO123旗下的AI智能LOGO生成器,只需输入品牌名称就能免费在线生成公司logo设计及配套企业VI,轻松打造您的个性品牌!

下载
  • 调用者无需担心函数内部意外改坏自己的数据
  • 并发场景下,多个 goroutine 拿到的都是各自副本,天然无共享、无竞争
  • 编译器更容易做逃逸分析和分配优化(小值类型常留在栈上)

代价是大结构体传参开销略高,这时就该考虑传指针——但注意:传指针仍是值拷贝(拷贝的是指针本身),只是副本指针和原指针指向同一地址。

哪些类型算“纯值类型”?关键看是否含引用字段

判断一个类型传参是否“真正隔离”,不能只看类型声明,而要看它实际持有的数据:

  • type A struct{ X int; Y string } → 纯值类型,拷贝即完全独立
  • type B struct{ Data []int; Info *string } → 表面是 struct,但含切片和指针,拷贝后仍共享底层数组和字符串内存

后者若需彻底隔离,就得手动深拷贝或用第三方库(如 copiergob 编解码)。

基本上就这些。Go 不绕弯子:一律值拷贝,区别只在于“拷什么”——值类型拷数据,“引用类型”拷的是描述数据位置的句柄(比如 slice header、map header、指针值)。理解这点,就不会被“为什么改了切片却影响原变量”这类问题卡住。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

311

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

246

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1428

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

606

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

546

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

539

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

156

2025.07.29

笔记本电脑卡反应很慢处理方法汇总
笔记本电脑卡反应很慢处理方法汇总

本专题整合了笔记本电脑卡反应慢解决方法,阅读专题下面的文章了解更多详细内容。

1

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 2.9万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号