首页 文章

为什么切片长度大于容量会产生运行时错误?

提问于
浏览
3

制作容量小于长度的切片

package main

    import fmt "fmt"

    func main(){

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

尝试运行时会出现以下错误 .

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

我的问题是容量能否小于长度?

如果'Yes'那么为什么会出现这个错误?
如果'No'那么为什么这是一个运行时错误,为什么不编译时?

2 回答

  • 13

    阅读Go Programming Language Specification .

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

  • 4

    不,容量不能小于长度 .

    切片是对数组的一部分的引用 . 切片的容量表示该后备阵列的大小 . 如果它的长度大于它的容量,那么它使用的内存是多少?

    以下不变量始终适用于切片s(除非您做了不安全的事情):

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

    您的代码会产生运行时错误而不是编译时错误,因为无法始终静态检测错误 . 在你的情况下它可能是,但考虑这个代码:

    package main
    
    import (
        "fmt"
        "rand"
    )
    
    func main() {
        k := make([]int, rand.Int(), rand.Int())
        fmt.Println(k)
    }
    

    传递给make的值在运行时才能知道 .

相关问题