【问题标题】:Slice index greater than length and less than capacity gives error大于长度且小于容量的切片索引给出错误
【发布时间】:2011-10-28 08:12:54
【问题描述】:

以下代码在运行时出错。

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],它运行良好。您能否解释一下容量对切片的确切含义。

【问题讨论】:

    标签: go


    【解决方案1】:

    您只是索引,因此索引必须小于长度。 relevant section of the Go specification 这么说

    表单的主要表达方式

    a[x]

    ...

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

    x 必须是整数值和 0

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

    【讨论】:

      【解决方案2】:

      阅读Go Programming Language Specification

      Length and capacity

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

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

      【讨论】:

        【解决方案3】:
        var slice = make([]b, 5, 10)
        

        等于

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

        不同的是,当你使用var slice = make([]b, 5, 10)时,你无法访问slice下的arrayslice := array[:5]表示slice的第一个元素是array[0]slice的长度是5,表示slice[0] == array[0], slice[1] == array[1], ... slice[4] == array[4]。因为您只能访问小于长度的索引(即0 &lt;= index &lt; length)。 slice的长度是5,array的长度是10,所以你可以访问array[8](0slice[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

        【讨论】:

          猜你喜欢
          • 2011-10-28
          • 2016-08-09
          • 1970-01-01
          • 2011-11-20
          • 1970-01-01
          • 2019-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多