切片索引大于长度且小于容量会导致错误。

huangapple go评论85阅读模式
英文:

Slice index greater than length and less than capacity gives error

问题

以下是翻译好的部分:

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

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],它会正常运行。你能解释一下切片的容量具体是什么意思吗?

英文:

Following code gives a error at runtime.

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))
}

Error is as follows.

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

While if k[0] or k[1] is printed, it runs fine. Can you please explain what exactly capacity means for slices.

答案1

得分: 2

你只是在进行索引,所以索引必须小于长度。Go规范的相关部分说道:

> 形式为
>
> a[x]
>
> 的主表达式
>
> ...
>
> 对于类型为A或*A的a,其中A是数组类型,或者对于类型为S的a,其中S是切片类型:
>
> x必须是一个整数值,且0 <= x < len(a)

然而,如果你在进行“切片”操作(例如a[6:9]),那么索引可以大于长度但必须在容量范围内。

英文:

You are simply indexing, so the index must be less than the length. The relevant section of the Go specification says that

> A primary expression of the form
>
> a[x]
>
> ...
>
> For a of type A or *A where A is an array type, or for a of type S
> where S is a slice type:
>
> x must be an integer value and 0 <= x < len(a)

However, if you were "slicing" (e.g. a[6:9]), then it would work with indexes that are greater than the length but within the capacity.

答案2

得分: 0

阅读Go编程语言规范

> 长度和容量
>
> 切片的容量是底层数组中分配空间的元素数量。在任何时候,以下关系成立:
>
> 0 <= len(s) <= cap(s)

英文:

Read the Go Programming Language Specification.

> Length and capacity
>
> The capacity of a slice is the number of elements for which there is
> space allocated in the underlying array. At any time the following
> relationship holds:
>
> 0 <= len(s) <= cap(s)

答案3

得分: 0

var slice = make([]b, 5, 10)等同于var array [10]b
slice := array[:5]
不同之处在于使用var slice = make([]b, 5, 10)时,无法通过slice访问array。而slice := array[:5]表示slice的第一个元素是array[0],slice的长度为5,也就是说slice[0] == array[0],slice1 == array1,... 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
英文:
var slice = make([]b, 5, 10)

is equal to

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

The difference is that when you use var slice = make([]b, 5, 10), you can't access the array under slice. The slice := array[:5] means the first element of slice is array[0] and the length of slice is 5, which means slice[0] == array[0], slice[1] == array[1], ... slice[4] == array[4]. Because you can only access the index that is less than the length(which means 0 &lt;= index &lt; length). The length of slice is 5 and the length of array is 10, so you can access array[8](0<=8<10) but can't access slice[8](8>5).

Full sample:

package main

import fmt &quot;fmt&quot;

func main(){

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

Reference

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

huangapple
  • 本文由 发表于 2011年8月17日 02:45:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/7083366.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定