当前位置: 首页 > news >正文

golang进阶知识专项-理解值传递

在 Go 语言中,所有函数的参数传递都是值传递(Pass by Value)。当你将一个变量作为参数传递给函数时,实际上传递的是该变量的副本,而不是变量本身。理解这一点对于避免常见的编程错误至关重要。根据不同的类型,以下作简要的区分和介绍

1. 基本类型(值类型)

例如:int, float, bool, string, struct 等类型。
函数内部操作的是原始值的副本,修改不会影响原变量。

func modifyValue(n int) {
    n = 100 // 修改的是副本
}

func main() {
    x := 10
    modifyValue(x)
    fmt.Println(x) // 输出 10,原值未变
}

2. 指针类型(T)

传递指针时,复制的是指针的副本,但副本和原指针指向同一块内存。
函数内通过指针修改的是原变量的值。

func modifyPointer(n *int) {
    *n = 100 // 通过指针修改原值
}

func main() {
    x := 10
    modifyPointer(&x)
    fmt.Println(x) // 输出 100
}

Tips:虽然指针是值传递,但通过间接访问可以修改原数据。


3. 引用类型(Slice、Map、Channel)

这些类型内部包含指向底层数据结构的指针,传递时复制的是它们的“描述符”(如切片的指针、长度、容量),而不是底层数据本身。
函数内对元素的修改会影响原变量,但修改描述符(如扩容切片)不会影响原变量。

func modifySlice(s []int) {
    s[0] = 100       // 修改底层数组,影响原切片
    s = append(s, 20  0) // 修改副本的描述符,原切片不受影响
}

func main() {
    s := []int{1, 2, 3}
    modifySlice(s)
    fmt.Println(s) // 输出 [100 2 3]
}

注意误区:如果进行append操作导致扩容,如切片这时可能会新分配数组,这时候原切片和参数副本的行为就会不同,会导致修改行为不符合预期。但函数内对 Map 的修改始终影响原数据,因为 Map 本身就是引用类型。Channel一般不存在扩容场景


关键总结

  • 值传递的本质:所有参数传递都是复制值的副本。

  • 指针和引用类型的表现:虽然传递的是副本,但通过指针或内部指针间接访问数据时,可以修改原数据。

  • 性能考虑

    • 大型结构体使用指针传递避免复制开销。
    • 切片、Map、Channel 本身是轻量级结构,直接传递即可。

相关文章:

  • 记录一次Spring事务失效导致的生产问题
  • 第七节:基于Winform框架的串口助手小项目---协议解析《C#编程》
  • DeepSeek开源周:五大创新项目详解
  • 监听 RabbitMQ 延时交换机的消息数、OpenFeign 路径参数传入斜杠无法正确转义
  • Docker 部署开源项目HivisionIDPhotos详细教程
  • 【个人学习总结】反悔贪心:反悔堆+反悔自动机
  • SPL 和 SQL 能不能融合在一起?
  • 使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅
  • 家政保洁维修行业有没有必要做小程序?
  • 搭建一个跳板服务器的全过程
  • 数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南
  • k倍区间(蓝桥杯 )
  • 基于Python的PDF特殊字体提取器开发实践
  • 3.3.2 Proteus第一个仿真图
  • ArcGIS操作:07 绘制矢量shp面
  • 服务器内存
  • 微机原理与汇编语言试题十二
  • 每日一题-哞叫题(蓝桥杯)【模拟】
  • 专业录音机的未来的市场需求点简析
  • 国内光子AI智能引擎:OptoChat AI在南京江北新区亮相
  • 汽车网站开发思路/济南seo关键词排名工具
  • 梭子手做鱼网站/网站开发建站
  • 网站上面的在线咨询是怎么做的/无锡网站制作优化
  • 河南app定制/互联网seo是什么
  • 青岛市黄岛区城市建设局网站/手机怎么创建网站
  • 党支部建设网站/产品推广文案怎么写