You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言切片上下界疑问:为何s[3:5]未触发越界panic?

Go切片未触发索引越界的原因解析

代码与输出对比

示例代码

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    fmt.Println("check 1: ",s, len(s))
    
    s = s[1:4]
    fmt.Println("check 2: ",s, len(s))

    s = s[3:5]
    fmt.Println("check 3: ",s, len(s))

    s = s[1:]
    fmt.Println("check 4: ",s, len(s))
}

实际执行输出

check 1:  [2 3 5 7 11 13] 6
check 2:  [3 5 7] 3
check 3:  [11 13] 2
check 4:  [13] 1

预期输出

check 1:  [2 3 5 7 11 13] 6
check 2:  [3 5 7] 3
panic: runtime error: slice bounds out of range [3:5]

问题核心

执行s = s[1:4]后,切片s的可见元素是[3,5,7],长度为3,但执行s = s[3:5]并未触发越界panic,反而返回了[11,13],这是为什么?

原因解释

Go的切片本质是底层数组的视图,它包含三个关键属性:

  • 指向底层数组的指针
  • len:当前切片可见的元素个数
  • cap:从指针指向的位置到底层数组末尾的元素总数

当执行s = s[1:4]时:

  • 原切片的底层数组是[2,3,5,7,11,13],len=6,cap=6
  • 新切片的指针指向原数组索引1(元素3),len=4-1=3,cap=6-1=5

也就是说,此时切片s虽然只能看到前3个元素,但底层数组从指针位置开始还有5个元素(3,5,7,11,13)。

Go对切片索引的规则是:切片的右边界(结束索引)允许达到当前切片的cap值,而非仅仅len值。只要右边界不超过cap,就不会触发越界panic。

所以执行s = s[3:5]时:

  • 起始索引3对应原数组的1+3=4位置(元素11)
  • 结束索引5对应原数组的1+5=6位置(开区间,实际取到索引5)
  • 最终切片取到原数组索引4、5的元素11,13,长度为5-3=2,完全在cap=5的范围内,因此不会报错。

如果将代码改为s = s[3:6],右边界6超过了当前切片的cap=5,才会触发slice bounds out of range的panic。

总结

  • 切片的len是可见元素数,cap是底层数组剩余可用元素数
  • 切片索引的右边界可以扩展到cap,而非局限于len
  • 只有当索引超出cap(或起始索引超出len)时,才会触发越界panic

内容的提问来源于stack exchange,提问作者vj sreenivasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:19:55