切片索引大于长度且小于容量会产生错误

时间:2011-08-16 18:45:34

标签: go

以下代码在运行时发出错误。

package main

import fmt "fmt"

func main(){

    type b []int
    var k = make([]b, 5, 10)
    fmt.Printf("%d\n",k[8])
    fmt.Printf("%d", len(k))
}

错误如下。

panic: runtime error: index out of range

runtime.panic+0x9e /go/src/pkg/runtime/proc.c:1060
        runtime.panic(0x453b00, 0x300203f0)
runtime.panicstring+0x94 /go/src/pkg/runtime/runtime.c:116
        runtime.panicstring(0x4af6c6, 0xc)
runtime.panicindex+0x26 /go/src/pkg/runtime/runtime.c:73
        runtime.panicindex()
main.main+0x8d C:/GOEXCE~1/basics/DATATY~1/slice.go:9
        main.main()
runtime.mainstart+0xf 386/asm.s:93
        runtime.mainstart()
runtime.goexit /go/src/pkg/runtime/proc.c:178
        runtime.goexit()
----- goroutine created by -----
_rt0_386+0xbf 386/asm.s:80

如果打印k[0]k[1],则运行正常。你能解释一下切片的容量究竟是什么意思吗?

3 个答案:

答案 0 :(得分:2)

您只是编制索引,因此索引必须小于长度。 relevant section of the Go specification表示

  

表单的主要表达式

     

一[X]

     

...

     

对于类型A或* A,其中A是数组类型,或类型为S   其中S是切片类型:

     

x必须是整数值且0 <= x <1。 LEN(a)中

但是,如果您正在“切片”(例如a[6:9]),那么它将适用于大于长度但在容量范围内的索引。

答案 1 :(得分:0)

阅读Go Programming Language Specification

  

Length and capacity

     

切片的容量是存在的元素数   在底层数组中分配的空间。随时有以下情况   关系成立:

0 <= len(s) <= cap(s)

答案 2 :(得分:0)

var slice = make([]b, 5, 10)

等于

var array [10]b
slice := array[:5]

区别在于,当您使用var slice = make([]b, 5, 10)时,无法访问array下的sliceslice := array[:5]表示slice的第一个元素是array[0],而slice的长度是5,这意味着slice[0] == array[0], slice[1] == array[1], ... slice[4] == array[4]。因为您只能访问小于长度(即0 <= index < length)的索引。 slice的长度为5,array的长度为10,因此您可以访问array[8](0 <= 8 <10)但不能访问slice[8]( 8> 5)。

完整样本:

package main

import fmt "fmt"

func main(){

    type b []int
    var array [10]b
    slice := array[:5]
    // []
    fmt.Printf("%d\n",slice[1])
    // []
    fmt.Printf("%d\n",array[8])
    // panic: runtime error: index out of range
    fmt.Printf("%d\n",slice[8])
}

参考

  1. https://blog.golang.org/go-slices-usage-and-internals