golang报错:slice bounds out of range

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]

分析:将需要的元素重新拷贝到一个新的切片里,若切片元素比较大,则建议切片元素使用指针;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值