当数组的长度不为空时,出现“恐慌:运行时错误:索引超出范围”

jij*_*iji 7 arrays string compiler-errors string-length go

我很难学习如何在 Go 中循环遍历一个字符串来做一些事情(特别是分离单词而不是包含元音)。

我写了这个代码片段:https : //play.golang.org/p/zgDtOyq6qf

这是我运行时遇到的错误:

panic: runtime error: index out of range

goroutine 1 [running]:
panic(0x1045a0, 0x1040a010)
    /usr/local/go/src/runtime/panic.go:500 +0x720
main.myFunc(0x114130, 0x4, 0x0, 0x0, 0x0, 0x3ba3)
    /tmp/sandbox960520145/main.go:19 +0x1a0
main.main()
    /tmp/sandbox960520145/main.go:10 +0x40
Run Code Online (Sandbox Code Playgroud)

我在这个论坛里搜了一下,有人说是数组长度的原因,但是这里不是这样的。我不知道如何解决这个问题。有人可以建议吗?

小智 10

首先我们来解释一下:

result := make([]string, 0, 4)
Run Code Online (Sandbox Code Playgroud)

化妆内置函数分配和初始化类型的对象[]string调用它Slicestring

切片内部

切片是数组段的描述符。它由一个指向数组的指针、段的长度和它的容量(段的最大长度)组成。

所以result := make([]string, 0, 4)分配和初始化一个类型[]stringlength = 0and的对象capacity = 4
result := make([]string, 4, 4)分配和初始化一个类型[]stringlength = 4and的对象capacity = 4,它等于result := make([]string, 4)

现在result := make([]string, 0, 4)和之间有什么区别result := make([]string, 4)

result := make([]string, 0, 4)此切片的基本阵列是使用空的含义result[0]将惊慌:运行时错误:索引超出范围。

result := make([]string, 4)此切片的基本阵列具有4个string元件,使用意result[0]result[1]result[2]result[3]是OK:

package main

import "fmt"

func main() {
    result := make([]string, 4)
    fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])
}
Run Code Online (Sandbox Code Playgroud)

输出:

"", "", "", "" 
Run Code Online (Sandbox Code Playgroud)

并且result := make([]string, 4)等于result := []string{"", "", "", ""}这个代码的意思:

"", "", "", "" 
Run Code Online (Sandbox Code Playgroud)

输出与上面的代码相同:

"", "", "", "" 
Run Code Online (Sandbox Code Playgroud)

追加的内置功能附加元素片的结尾。如果它有足够的容量,目标将被重新切片以容纳新元素。如果没有,将分配一个新的底层数组。Append 返回更新后的切片。因此有必要将 append 的结果存储在保存切片本身的变量中:

slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)
Run Code Online (Sandbox Code Playgroud)

作为一种特殊情况,将字符串附加到字节切片是合法的,如下所示:

slice = append([]byte("hello "), "world"...)
Run Code Online (Sandbox Code Playgroud)

现在在你的代码里面的函数myFunc之后result := make([]string, 0, 4),你可以使用append,就像这个工作代码(Go Playground):

package main

import "fmt"

func main() {
    result := []string{"", "", "", ""}
    fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])
}
Run Code Online (Sandbox Code Playgroud)

您可以简化该代码,例如以下工作代码(The Go Playground):

"", "", "", "" 
Run Code Online (Sandbox Code Playgroud)


End*_*imo 3

问题是您正在创建一个长度为0,但最大容量为 的切片4,但同时您试图将一个值分配给所创建切片的第零个索引(通常为空)。这就是您收到index out of range error.

result := make([]string, 0, 4)
fmt.Println(len(result)) //panic: runtime error: index out of range
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式更改此代码:

result := make([]string, 4)
Run Code Online (Sandbox Code Playgroud)

这意味着容量将与切片长度相同。

fmt.Println(cap(result)) // 4
fmt.Println(len(result)) // 4
Run Code Online (Sandbox Code Playgroud)

您可以在这里阅读有关数组切片映射的信息: https: //blog.golang.org/go-slices-usage-and-internals