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)
-