golang踩坑集锦

593 阅读2分钟

golang踩坑集锦

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情 >>

1. ineffassign

lint 警告: ineffectual assignment to content (ineffassign)

为什么会有这个警告,原因是声明的变量后续并没有用到。ineffassign检测 Go 代码中的无效赋值

出现报错的地方

pair, rerr = Reset("data/", "data/50", 60, *pair)

go强制的一个要求,必须要对这些变量做处理使用,报错信息才会消失

这里的pair之前有定义过,调用Reset函数之后会对其值进行更新。更新之后的这个值在后续的程序里并没有被用到,所以产生这个报错。

2. slice

代码中出现了t.tasks = t.tasks[i:] 的写法,既不能释放内存,又会导致下标错误

2.1 slice原理

  • golang中的切片(slice)底层实现还是数组。对slice一定要谨慎使用append操作。如果切片一直存在,那么数组也不会被释放。所以这里可能存在严重的内存浪费行为。
  • 如果cap未变化时,slice是对数组的引用,并且append会修改被引用数组的值。append操作导致cap变化后,会复制被引用的数组,然后切断引用关系。

2.2 golang关于slice的内存回收

  • *1.截取长slice中的一段导致长slice未释放
    • 例如从文件内容中查找指定的内容,则可能会发生这种情况:读取了整个文件,返回了一个很大的[]byte,但最终返回的是一个很小的[]byte,这时候底层的数组不会被释放!
    • 解决方案:这时,最好就是将获取到的结果append到全新的切片中。(新建一个长度为0的slice,将需要的一小段slice使用append方法添加到新的slice。再将原来的slice置为nil。)
  • 2.配合gc,及时将不再使用的slice置为nil
    • 如果slice中包含很多元素,再只有一小部分元素需要使用的情况下。建议重新分配一个slice将需要保留的元素加入其中,将原来的长slice整个置为nil。
  • 3.不用的元素置为nil
    • 另外,还有一种可能,就是切片中存的是指针,当缩小切片的范围时,范围外的指针仍然存在!同样会阻碍GC的进行!——做法:将不需要的元素置为nil再切片就可以释放内存了
  • 其他

2.3 一般用法

  • out of range需要检查哪里越界了,一般是逻辑写的有问题,没有处理好边界条件
  • 队列、栈的用法 queue = queue[1:] stack = stack[:len(stack)-1]
  • 遍历切片for _, num := range nums[2:]
  • 向前安全追加数组
    • tmpArray := array
      array = make([]uint64, len(tmpArray)+len(add))
      copy(array[:len(add)], add)
      copy(array[len(add):], tmpArray)
      

参考

[Golang查缺补漏(一)](www.cnblogs.com/larryzeal/p…)