Why slice length greater than capacity gives runtime error?
在容量小于长度的地方做一个切片
1 2 3 4 5 6 7 8 9 10 11 | package main import fmt"fmt" func main(){ type b []int var k = make([]b, 10, 5) fmt.Printf("%d ",k[8]) } |
尝试运行时出现以下错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | panic: runtime error: makeslice: cap out of range runtime.panic+0x9e /go/src/pkg/runtime/proc.c:1060 runtime.panic(0x453b00, 0x30020390) runtime.panicstring+0x94 /go/src/pkg/runtime/runtime.c:116 runtime.panicstring(0x4afd6c, 0x40d80c) runtime.makeslice+0x70 /go/src/pkg/runtime/slice.c:24 runtime.makeslice(0x44302c, 0xa, 0x0, 0x5, 0x0, ...) main.main+0x45 C:/GOEXCE~1/basics/DATATY~1/slice.go:8 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 |
号
我的问题是容量能小于长度吗?
如果"是",那么为什么会出现此错误?如果"否",那么为什么这是一个运行时错误,为什么不是编译时?
不,容量不能小于长度。
切片是对数组一部分的引用。切片的容量表示该支持数组的大小。如果它的长度大于它的容量,那么它使用的内存是什么?
以下不变量始终适用于切片(除非您做了不安全的事情):
1 | 0 <= len(s) <= cap(s) |
您的代码会产生运行时错误,而不是编译时错误,因为不能总是静态地检测到该错误。在您的情况下,它可能是,但请考虑以下代码:
1 2 3 4 5 6 7 8 9 10 11 | package main import ( "fmt" "rand" ) func main() { k := make([]int, rand.Int(), rand.Int()) fmt.Println(k) } |
号
传递给make的值在运行时之前无法知道。
阅读GO编程语言规范。
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:
1 0 <= len(s) <= cap(s)
号