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

我很难学习如何在 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

我在这个论坛上搜了一下,有人说是数组长度的问题,但是这里不是这样的。我无法弄清楚如何解决这个问题。有人可以提出一些建议吗?


米脂
浏览 369回答 3
3回答

BIG阳

首先让我们解释一下:result := make([]string, 0, 4)make内置函数分配和初始化一个[]stringcall it Sliceof类型的对象string切片内部:切片是数组段的描述符。它由指向数组的指针、段的长度及其容量(段的最大长度)组成。所以result := make([]string, 0, 4)分配和初始化一个类型[]string为length = 0and的对象capacity = 4。并result := make([]string, 4, 4)分配和初始化一个类型[]string为length = 4and的对象capacity = 4,它等于result := make([]string, 4)。result := make([]string, 0, 4)现在和有什么区别result := make([]string, 4):这个result := make([]string, 0, 4)Slice 的底层数组是空的,这意味着使用result[0]will panic: runtime error: index out of range。这个result := make([]string, 4)Slice 的底层数组有 4 个string元素,意思是使用result[0], result[1], result[2],result[3]是可以的:package mainimport "fmt"func main() {&nbsp; &nbsp; result := make([]string, 4)&nbsp; &nbsp; fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])}输出:"", "", "", ""&nbsp;并且result := make([]string, 4)等于result := []string{"", "", "", ""}表示这段代码:package mainimport "fmt"func main() {&nbsp; &nbsp; result := []string{"", "", "", ""}&nbsp; &nbsp; fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])}输出与上面的代码相同:"", "", "", ""&nbsp;append内置函数将元素附加到切片的末尾。如果它有足够的容量,则重新划分目标以容纳新元素。如果没有,将分配一个新的底层数组。Append 返回更新后的切片。因此有必要将 append 的结果存储在保存切片本身的变量中:slice = append(slice, elem1, elem2)slice = append(slice, anotherSlice...)作为一种特殊情况,将字符串附加到字节切片是合法的,如下所示:slice = append([]byte("hello "), "world"...)现在在你的代码里面的函数myFunc之后result := make([]string, 0, 4),你可以使用append,像这个工作代码(The Go Playground):package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "strings")func main() {&nbsp; &nbsp; strs := strings.Fields("Political srt")&nbsp; &nbsp; fmt.Println(len(strs)) // It's not empty so why index out of range&nbsp; &nbsp; fmt.Println(strs, strs[0], strs[1])&nbsp; &nbsp; fmt.Println(strings.ContainsAny(strs[0], "eaiuo"))&nbsp; &nbsp; fmt.Println(myFunc("Political srt"))}func myFunc(input string) []string {&nbsp; &nbsp; strs := strings.Fields(input)&nbsp; &nbsp; result := make([]string, 0, 4)&nbsp; &nbsp; for i := 0; i < len(strs); i++ {&nbsp; &nbsp; &nbsp; &nbsp; if strings.ContainsAny(strs[i], "eaiu") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = append(result, strs[i])&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = append(result, strs[i])&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return result}您可以简化该代码,例如这个工作代码(The Go Playground):package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "strings")func main() {&nbsp; &nbsp; fmt.Println(myFunc("Political srt"))}func myFunc(input string) []string {&nbsp; &nbsp; strs := strings.Fields(input)&nbsp; &nbsp; result := make([]string, 0, 4)&nbsp; &nbsp; for _, s := range strs {&nbsp; &nbsp; &nbsp; &nbsp; if strings.ContainsAny(s, "eaiu") {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = append(result, s)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return result}

守着星空守着你

问题是您正在创建一个长度为 的切片0,但最大容量为4,但同时您正试图为创建的切片的第零个索引分配一个值,该索引通常为空。这就是您收到index out of range error.result := make([]string, 0, 4)fmt.Println(len(result)) //panic: runtime error: index out of range您可以使用以下方法更改此代码:result := make([]string, 4)这意味着容量将与切片长度相同。fmt.Println(cap(result)) // 4fmt.Println(len(result)) // 4您可以在此处阅读有关数组、切片和映射的信息:https ://blog.golang.org/go-slices-usage-and-internals

慕桂英546537

出现索引超出范围错误,因为您没有result以足够的长度初始化数组。在myFunc中,您有:result&nbsp;:=&nbsp;make([]string,&nbsp;0,&nbsp;4)这将创建一个字符串切片,该切片具有长度为 4 的底层数组,但由于您已将切片长度声明为 0,因此切片无法访问底层数组中的任何元素。所以 evenresult[0]超出了可用索引的范围。要解决此问题,只需提供足够大的长度参数即可make:result&nbsp;:=&nbsp;make([]string,&nbsp;4,&nbsp;4)您可以在此处阅读有关切片如何操作的更多信息。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go