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

关于go里切片作为函数参数时是引用传递还是值传递

问题起因

写一道回溯算法题,把ans二维数组作为函数参数传入,想在函数里面,不停地append,最后返回ans
实际发现ans打印出来是空的,就很奇怪,因为我是事先分配好空间的,理论上不会发生扩容,底层数组是共用的,咋回事

func permute(nums []int) [][]int {ans := make([][]int, 0, len(nums)*len(nums))item := append([]int{}, nums...)backtracking(0, item, nums,&ans)return ans
}func backtracking(i int, cur, nums []int, ans [][]int) {if i == len(nums) {tmp := slices.Clone(cur)ans = append(ans, tmp)return}for j:=i;j<len(nums);j++ {swap(i, j, cur)backtracking(i+1, cur, nums, ans)swap(i, j, cur)}
}func swap(i,j int, nums []int) {nums[i], nums[j] = nums[j], nums[i]
}

传递指针问题解决

*ans [][]int

分析原因

切片里不止有底层数组啊,还有Len Cap这些基础数据类型;修改是不可见的
在Go语言中,切片(slice)作为函数参数传递时,是通过值传递的,但这里传递的值是切片头(slice header),其中包含指向底层数组的指针、长度和容量。这意味着函数内部可以通过这个指针修改底层数组的元素,但如果对切片进行追加(append)操作,可能会改变切片头的值(例如长度和指针),这些更改不会反映到外部切片中,因为函数内部操作的是切片头的副本。

import "slices"func permute(nums []int) [][]int {ans := make([][]int, 0)n := len(nums)// 创建当前排列的副本,用于回溯操作cur := make([]int, n)copy(cur, nums)// 定义闭包函数var backtrack func(int)backtrack = func(i int) {if i == n {// 将当前排列添加到答案中tmp := slices.Clone(cur)ans = append(ans, tmp)return}for j := i; j < n; j++ {// 交换元素cur[i], cur[j] = cur[j], cur[i]backtrack(i + 1)// 回溯,恢复交换cur[i], cur[j] = cur[j], cur[i]}}backtrack(0)return ans
}

参考,最下面评论区

http://www.wxhsa.cn/company.asp?id=5120

相关文章:

  • DRAN读写循环
  • 数据结构操作相关
  • Neisbitt 不等式的证法
  • 端口转发神器Rinetd:轻量级安装与配置指南
  • C语言中递归思想的应用
  • WITH RECURSIVE 递归公用表表达式(CTE)
  • leetcode 3541. 找到频率最高的元音和辅音 便捷
  • 匿名递归与不动点组合子
  • Markdown学习Day01
  • flutter compass结构代码分析
  • 25.9.15
  • 二十八、共享内存多处理器的基本概念
  • 详细介绍:【ARMv7】系统复位上电后的程序执行过程
  • C#高级语法
  • 配置Maven
  • 那两年的回忆录
  • DDR4基本介绍
  • 网络同步预测-Prediction
  • 二十五、多处理器的基本概念 (SISD/SIMD/MIMD)
  • java课堂问题2
  • 集训总结(六)
  • GAS_Aura-Prediction GAS
  • PromptPilot 产品发布:火山引擎助力AI提示词优化的新利器
  • 安装window版本docker
  • 已严肃完成今日特征多项式大学习
  • docker部署Gitlab社区版,步骤以及外网访问出现502的解决方式 - 实践
  • python_Day21_mysql(2)
  • .zip用法
  • vue2使用pnpm编译打包时的错误处理
  • 中南上课第一天