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

golang 传参使用切换和数组有什么区别?

一、快速记忆先记核心方面数组切片本质固定长度的值指向底层数组的视图传参时整个复制只复制描述信息24字节函数内改元素不影响外面影响外面函数内改长度不允许长度固定外面看不到需返回二、详细对比4个方面1️⃣ 内存和性能数组传参复制全部数据func consumeArray(arr [1000000]int) { // 100万个int约8MB // 函数调用时会完整复制这8MB数据 } func main() { huge : [1000000]int{} consumeArray(huge) // 慢复制8MB }切片传参只复制小纸条func consumeSlice(slice []int) { // 只复制24字节指针长度容量 // 不管底层数组多大都只复制24字节 } func main() { huge : make([]int, 1000000) // 底层8MB数组 consumeSlice(huge) // 快只复制24字节 }结论大数组用切片传参性能好得多。2️⃣ 修改内部元素的影响package main import fmt // 数组改副本不影响外面 func modifyArray(arr [3]int) { arr[0] 999 } // 切片改原数组影响外面 func modifySlice(slice []int) { slice[0] 999 } func main() { // 数组测试 arr : [3]int{1, 2, 3} modifyArray(arr) fmt.Println(数组传参后:, arr) // [1 2 3] 没变 // 切片测试 slice : []int{1, 2, 3} modifySlice(slice) fmt.Println(切片传参后:, slice) // [999 2 3] 变了 }输出数组传参后: [1 2 3] 切片传参后: [999 2 3]3️⃣ 修改长度增删元素这是最坑的地方细看package main import fmt // 尝试在函数内增加元素 func addElement(s []int) { s append(s, 100) // 增加一个元素 fmt.Println(函数内部:, s) // [1 2 3 100] } func main() { slice : []int{1, 2, 3} addElement(slice) fmt.Println(函数外部:, slice) // [1 2 3] 没变 }为什么因为切片有3个信息ptr指针指向底层数组len长度当前有多少元素cap容量最多能装多少传参时复制了这3个信息所以函数内的len是3append后变成4但改的是副本外面的len仍然是3解决方案返回新切片func addElement(s []int) []int { s append(s, 100) return s // 返回新的切片 } func main() { slice : []int{1, 2, 3} slice addElement(slice) // 接收返回值 fmt.Println(slice) // [1 2 3 100] 成功 }4️⃣ 函数签名类型系统// 数组长度是类型的一部分 func process(arr1 [3]int) {} // 只能接收长度3的数组 func process(arr2 [5]int) {} // 这是不同的类型 // 切片长度不是类型的一部分 func process(slice []int) {} // 可以接收任何长度的int切片 func main() { arr3 : [3]int{1, 2, 3} arr5 : [5]int{1, 2, 3, 4, 5} process(arr3) // ✅ 可以 process(arr5) // ❌ 编译错误类型不匹配 slice : []int{1, 2, 3} process(slice) // ✅ 可以 slice2 : []int{1, 2, 3, 4, 5} process(slice2) // ✅ 也可以 }结论切片更灵活数组太死板。三、特殊情况切片扩容当append时容量不够会重新分配底层数组func modifyWithAppend(s []int) { s append(s, 4) // 如果容量够继续用原数组 s[0] 100 } func main() { // 情况1容量够 slice1 : make([]int, 3, 10) // 长度3容量10 slice1[0], slice1[1], slice1[2] 1, 2, 3 modifyWithAppend(slice1) fmt.Println(容量够:, slice1) // [100 2 3] 元素变了但长度还是3 // 情况2容量不够 slice2 : []int{1, 2, 3} // 长度3容量3不够了 modifyWithAppend(slice2) fmt.Println(容量不够:, slice2) // [1 2 3] 完全没变 // 因为append时重新分配了新数组跟外面的数组没关系了 }四、如何选择实际开发建议你的需求选择理由日常开发数据会变动切片99%的情况都用切片数组大小固定不变如坐标点数组或切片均可但切片更灵活函数需要修改长度切片 返回新切片这是标准做法想保护数据不被函数修改数组或复制切片用copy()复制切片性能极端敏感要避免扩容切片 make预分配容量make([]int, 0, 1000)函数间传递超大数据切片必须是切片避免复制开销五、实用技巧技巧1想保护切片不被修改func protectData(original []int) { // 复制一份 copy : make([]int, len(original)) copyData : append([]int{}, original...) // 更简洁的复制 // 让其他函数用副本 dangerousFunction(copyData) }技巧2明确需要修改切片func modifySlice(s []int) []int { // 修改... s append(s, 999) return s // 始终返回 } // 调用时 mySlice modifySlice(mySlice)技巧3面试常问的坑func test(s []int) { s append(s, 4) s[0] 100 } func main() { s : []int{1, 2, 3} test(s) fmt.Println(s) // 请问输出什么 } // 答案[1 2 3] // 因为append后s变了但外面的s没变总结口诀数组笨重传全部改了外面不关注。切片轻巧传地址增删改要懂规矩。改元素时内外通要变长度得返回送。最后记住实际写代码99%都用切片数组只有在极特殊场景比如需要固定长度类型的key、极小数组才用。
http://www.rkmt.cn/news/1374842.html

相关文章:

  • 上位机软件开发框架怎么选?WinForm/WPF/Avalonia/QT
  • Trae+Playwright MCP:构建CI/CD就绪的浏览器自动化基础设施
  • Claude+CC‑Switch安装下载-Windows+macOS 安装
  • 测试前端代码!
  • 保姆级教程:用Rufus制作Proxmox VE 8.1启动盘,一次点亮你的旧服务器
  • 2026 中国 GEO 优化定制技术解析:企业资质代办的核心作用深度测评
  • 第二周 学习
  • 多模态融合与预训练语言模型在死因自动分类中的应用
  • 基于流态分割的VBNN湍流建模与PODNN降阶方法实践
  • MinatoLoader:动态负载均衡解决PyTorch数据加载瓶颈,GPU利用率提升至90%+
  • 2026年评价高的昆山扫描电镜/昆山全自动扫描电镜/扫描电镜产品/SEM扫描电镜推荐厂家精选 - 品牌宣传支持者
  • 安全稀疏矩阵乘法:基于二叉树递归传播的MPC算法优化详解
  • VR+机器学习:跨语言阅读障碍识别的新范式
  • AscendSiPBoost信号处理加速库架构与实战
  • JavaScript 高频基础面试题
  • 刚出炉的 Codeforces Round 1100 B 题:一眼像交换,实则一行贪心公式
  • 阿里云ECS CPU 100%排查:5分钟定位挖矿病毒的原生命令链
  • 抖音a_bogus生成原理与Python逆向实现全解析
  • 2026年免费照片去水印软件App推荐,一看就会的保姆级详细教程
  • 12周学习笔记
  • 2026年照片去水印免费软件保姆级教程!学会这几招,告别水印烦恼
  • AArch64虚拟内存系统架构与权限控制详解
  • 量子纠错技术:从理论到实践的突破
  • DVWA与Pikachu双靶场协同部署:宝塔+PHPStudy双环境实战指南
  • PyTorch零基础保姆级安装与测试教程
  • 为什么企业要把 EDR 放在终端,HIDS 放在主机?
  • 2026年重磅解读:横向测评5大耐高温吸塑包装供应商避坑手册+底价参考
  • 离线的银河麒麟系统部署ollama
  • Windows下玩转NVMe:除了Identify,用Intel MAS命令行还能做这些高级操作
  • AI规范编程:从SDD理念到Spec-Kit落地实践