1. 场景1
slice元素删除时,由于下标越界会报错“slice bounds out of range", 代码示例如下:
package main
import (
"fmt"
)
func main() {
var numList []int
numList = append(numList, 1)
numList = append(numList, 2)
fmt.Println("numList len:", len(numList))
numList = append(numList[0:1], numList[2:]...) // 第一次:正常删除下标为1的元素
fmt.Println("numList:", numList)
fmt.Println("numList len:", len(numList))
numList = append(numList[0:1], numList[2:]...) // 第二次:numList[2]越界了
fmt.Println("numList:", numList)
}
运行结果如下:
numList len: 2
numList: [1]
numList len: 1
panic: runtime error: slice bounds out of range
goroutine 1 [running]:
panic(0x49b100, 0xc04200c060)
c:/go/src/runtime/panic.go:500 +0x1af
main.main()
E:/Study-Data/GO/Test/src/dbTest/main.go:17 +0x5f7
分析:
第一次调用numList[2:]...,其实下标2已结越界了,但是执行并不会报错,猜测原因可能是golang特殊处理了,为了方便删除切片的最后一个元素,否则,开发起来比较麻烦,每次删除都需要判断是否是最后一个元素,删除最后一个元素都得加if else判断;
第二次调用numList[2:]...,由于下标已经比slice总长度还要大1, 因此报错;
2. 场景2
“slice bounds out of range", 另外一种场景下,出错比较不容易被发现,如需要在循环中删除元素的情况, 示例代码如下:
package main
func main() {
var numList []int
numList = append(numList, 1)
numList = append(numList, 2)
numList = append(numList, 3)
for i, v := range numList {
if 1 == v {
numList = append(numList[0:i], numList[i+1:]...) // 第一次:正常删除下标为i的元素
}
if 3 == v {
numList = append(numList[0:i], numList[i+1:]...) // 第二次:删除下标为i的元素报错
}
}
}
分析:
在for循环中需要多次删除元素时,删除最后几个元素时很可能产生越界,而且这种越界编码时不易察觉;
若是我们需要循环删除多个切片运输,该如何处理呢?一些是一点思路,示例如下:
package main
import (
"fmt"
)
func main() {
var srcList []int
srcList = append(srcList, 1)
srcList = append(srcList, 2)
srcList = append(srcList, 3)
fmt.Println("srcList:", srcList)
var dstList []int
for _, v := range srcList {
if v != 1 && v != 3 {
dstList = append(dstList, v) // 排除值为1和3的元素
}
}
fmt.Println("dstList:", dstList)
}
输出如下:
srcList: [1 2 3] dstList: [2]
分析:将需要的元素重新拷贝到一个新的切片里,若切片元素比较大,则建议切片元素使用指针;
本文探讨了Go语言中切片操作可能导致的下标越界错误,包括直接删除元素和循环删除元素时的常见问题,并提供了一种通过创建新切片来避免这些问题的方法。

365

被折叠的 条评论
为什么被折叠?



