Golang切片copy踩坑

简介: Golang切片copy踩坑

前言


  在刷题的时候,有时候写dfs,我总喜欢拼凑切片,但是在debug的时候发现切片总是莫名结果会多出很多零,这就引起了我的好奇心,为什么我拼凑切片会出错,错在哪里?

错误示范

  见下,我的目标是去除原切片下标i的元素,组成新的切片,进行下一次的递归

func main() {
  cnt := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
  errDemoDfs(cnt)
}
func errDemoDfs(cnt []int) {
  for i := 0; i < len(cnt); i++ {
    nextCnt := make([]int, len(cnt)-1)
    copy(nextCnt, cnt[:i])
    copy(nextCnt, cnt[i+1:])
    fmt.Println(nextCnt)
    errDemoDfs(nextCnt)
  }
}
...
[2 3 4 5 6 7 8 9]
[3 4 5 6 7 8 9 0]
[4 5 6 7 8 9 0 0]
[5 6 7 8 9 0 0 0]
[0 0]
[0]
[]
....

错误原因

  看输出发现,怎么新切片末尾是0,和我预取的结果不一致啊,why?随后debug

  发现原切片,cnt[:i],cnt[i+1:],都是正常的。恍然大悟!原来是我copy用错了

copy的用法:

1. copy(dst,src)

2. 拷贝min(len(dst),len(src))个元素

3. 每次都从dst下标0开始赋值

看第三个步骤,每次都从下标0开始赋值,也就是说

copy(nextCnt, cnt[:i])
copy(nextCnt, cnt[i+1:])

cnt[i+1:]的元素覆盖了cnt[:i]

有时候深拷贝切片我会用copy,然后遇到想要去除一个元素的情况,我偷懒也用copy,这就导致bug出现了

正常用法

那么如果想要深拷贝,并且去除原数组的一个元素该如何写呢

func main() {
  cnt := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
  acDemoDfs(cnt)
}
func acDemoDfs(cnt []int) {
  for i := 0; i < len(cnt); i++ {
    nextCnt := make([]int, 0, len(cnt)-1)
    nextCnt = append(nextCnt, cnt[:i]...)
    nextCnt = append(nextCnt, cnt[i+1:]...)
    fmt.Println(nextCnt)
    acDemoDfs(nextCnt)
  }
}
目录
相关文章
|
3月前
|
Go
Golang语言之切片(slice)快速入门篇
这篇文章是关于Go语言中切片(slice)的快速入门教程,详细介绍了切片的概念、定义方式、遍历、扩容机制、使用注意事项以及相关练习题。
38 5
|
4月前
|
监控 Serverless Go
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
|
6月前
|
Go
【golang】golang 字符串切片排序
【golang】golang 字符串切片排序
72 1
|
存储 Java Go
Golang 语言中数组和切片的区别是什么?
Golang 语言中数组和切片的区别是什么?
67 0
|
存储 大数据 Go
100天精通Golang(基础入门篇)——第11天:深入解析Go语言中的切片(Slice)及常用函数应用
100天精通Golang(基础入门篇)——第11天:深入解析Go语言中的切片(Slice)及常用函数应用
107 0
|
7月前
|
Go 索引
Golang深入浅出之-切片(Slices)入门:创建、操作与扩容机制
【4月更文挑战第20天】Go语言中的切片是动态数组,提供灵活的操作和自动扩容。本文介绍了切片的创建(通过`make()`、数组创建和切片字面量)、基本操作(索引访问、切片、赋值追加和遍历)以及扩容机制(首次和后续扩容策略)。此外,还强调了切片与底层数组的关系、切片越界问题、`append()`的使用以及理解切片的关键点,帮助提升Go编程效率和代码质量。
180 0
|
7月前
|
程序员 Go
第七章 Golang数组和切片
第七章 Golang数组和切片
55 2
|
7月前
|
Go C++ Java
C/C++每日一练(20230408) 删除无效括号、合并K个升序链表、四数之和
C/C++每日一练(20230408) 删除无效括号、合并K个升序链表、四数之和
57 0
C/C++每日一练(20230408) 删除无效括号、合并K个升序链表、四数之和
|
算法 中间件 程序员
golang中的异常和切片
golang中的异常和切片
|
JavaScript 前端开发 Go
正确使用 Golang 循环创建新切片的方式
正确使用 Golang 循环创建新切片的方式