为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
米脂 2022-03-03 15:09:53
我很难学习如何在 Go 中遍历一个字符串来做一些事情(特别是,将单词分开而不是包含元音)。我写了这个代码片段: https: //play.golang.org/p/zgDtOyq6qf。这是我在运行它时遇到的错误:panic: runtime error: index out of rangegoroutine 1 [running]:panic(0x1045a0, 0x1040a010)    /usr/local/go/src/runtime/panic.go:500 +0x720main.myFunc(0x114130, 0x4, 0x0, 0x0, 0x0, 0x3ba3)    /tmp/sandbox960520145/main.go:19 +0x1a0main.main()    /tmp/sandbox960520145/main.go:10 +0x40我在这个论坛上搜了一下,有人说是数组长度的问题,但是这里不是这样的。我无法弄清楚如何解决这个问题。有人可以提出一些建议吗?
查看完整描述

3 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

首先让我们解释一下:


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 main


import "fmt"


func main() {

    result := make([]string, 4)

    fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])

}

输出:


"", "", "", "" 

并且result := make([]string, 4)等于result := []string{"", "", "", ""}表示这段代码:


package main


import "fmt"


func main() {

    result := []string{"", "", "", ""}

    fmt.Printf("%q, %q, %q, %q \n", result[0], result[1], result[2], result[3])

}

输出与上面的代码相同:


"", "", "", "" 

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 main


import (

    "fmt"

    "strings"

)


func main() {

    strs := strings.Fields("Political srt")

    fmt.Println(len(strs)) // It's not empty so why index out of range

    fmt.Println(strs, strs[0], strs[1])

    fmt.Println(strings.ContainsAny(strs[0], "eaiuo"))

    fmt.Println(myFunc("Political srt"))

}


func myFunc(input string) []string {

    strs := strings.Fields(input)

    result := make([]string, 0, 4)

    for i := 0; i < len(strs); i++ {

        if strings.ContainsAny(strs[i], "eaiu") {

            result = append(result, strs[i])

        } else {

            result = append(result, strs[i])

        }

    }

    return result

}

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


package main


import (

    "fmt"

    "strings"

)


func main() {

    fmt.Println(myFunc("Political srt"))

}


func myFunc(input string) []string {

    strs := strings.Fields(input)

    result := make([]string, 0, 4)

    for _, s := range strs {

        if strings.ContainsAny(s, "eaiu") {

            result = append(result, s)

        }

    }

    return result

}


查看完整回答
反对 回复 2022-03-03
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

问题是您正在创建一个长度为 的切片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)) // 4

fmt.Println(len(result)) // 4

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


查看完整回答
反对 回复 2022-03-03
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

出现索引超出范围错误,因为您没有result以足够的长度初始化数组。

myFunc中,您有:

result := make([]string, 0, 4)

这将创建一个字符串切片,该切片具有长度为 4 的底层数组,但由于您已将切片长度声明为 0,因此切片无法访问底层数组中的任何元素。所以 evenresult[0]超出了可用索引的范围。

要解决此问题,只需提供足够大的长度参数即可make

result := make([]string, 4, 4)

您可以在此处阅读有关切片如何操作的更多信息。


查看完整回答
反对 回复 2022-03-03
  • 3 回答
  • 0 关注
  • 368 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号