【问题标题】:Why this code is generating array index out of bound?为什么这段代码生成的数组索引越界?
【发布时间】:2018-04-02 21:38:00
【问题描述】:

过去 5 到 6 个小时,我一直在弄清楚为什么这段代码会在运行时生成数组索引越界错误。我无法找出原因。你能告诉我需要什么修改来纠正这个代码吗?

spotsArr        := make(map[int][]map[int64][]int)
for ind, availableSpot := range availableSpots {
            spotsArr[availableSpot.Uid][ind] = make(map[int64][]int)
            spotsArr[availableSpot.Uid][ind][availableSpot.Date] = []int{availableSpot.SpotSlug}

}
fmt.Println(spotsArr)

编辑 1:在此处查看完整代码 https://play.golang.org/p/Smm0BFgtNp

编辑 2:实际上我需要做的是以如下格式获取输出:

{ uid: { date: {spot_slug, spot_slug} } }

{ 86: { 1536710400: {1000, 1200, 900},
      { 1536105600: {900} } }

【问题讨论】:

  • playground 中演示索引越界错误的简短而完整的代码将是完美的。当我尝试创建一个时,发生了很多其他错误:play.golang.org/p/HdkjoU0KXy
  • @har07 感谢回复的小伙伴,请检查代码,我已经更新了问题。
  • 你能说一下你想得到什么结果吗?

标签: arrays go slice


【解决方案1】:

正如错误消息所暗示的那样,错误是因为您试图在索引上分配大于切片长度的元素。为了消除错误,您可以将切片初始化为至少与您要使用的索引一样多的长度:

....
spotsArr[availableSpot.Uid] = make([]map[int64][]int, ind+1, ind+1)
spotsArr[availableSpot.Uid][ind] = make(map[int64][]int)
....

但是,当您进一步澄清了所需的输出时,您似乎一开始就不需要 slice。您需要 Uid 的映射,其中每个键的值都是 Date 的映射:

spotsArr := make(map[int]map[int64][]int)
for _, availableSpot := range availableSpots {
    if _, ok := spotsArr[availableSpot.Uid]; !ok {
        spotsArr[availableSpot.Uid] = make(map[int64][]int)
    }
    spotsArr[availableSpot.Uid][availableSpot.Date] = append(spotsArr[availableSpot.Uid][availableSpot.Date],availableSpot.SpotSlug)
}
fmt.Println(spotsArr)

playground

鉴于最后两个数据的日期相同,输出如下:

map[86:map[1534896000:[900] 1535500800:[900] 1536105600:[900] 1537315200:[900 900]]]

【讨论】:

  • 非常感谢 har07,您为我节省了大量时间。赞! :)
【解决方案2】:

spotsArr 是一个 int 映射到一个映射数组的映射 - map[int][]...

spotsArr        := make(map[int][]map[int64][]int)

在这一行,您尝试分配给该数组的索引,该数组还没有成员:

spotsArr[availableSpot.Uid][ind] = make(map[int64][]int)

您是说将这个点availableSpot.Uid 设置为某个值(很好),但随后将索引 ind 设置为一个没有成员的数组中的某个值(不好)。为了解决这个问题,我建议尝试在每一行上做更少的事情,以便更清楚问题出在哪里和是什么。您可以这样做来修复语法错误:

spotsArr[availableSpot.Uid] = []map[int64][]int{make(map[int64][]int)}

但我想不出您为什么要将地图上的索引设置为您正在遍历的 Uid 的索引(您的代码执行 [Ind])。如果可以的话,我会尽量减少复杂和混乱,并将其分散在几行以明确意图。

PS 给人们一个可以运行的代码示例(即包括所有使用的结构),这样更容易提供帮助。

PPS 感谢您提供的代码示例,这使其更清晰。

【讨论】:

  • 感谢 Kenny 的回复,我在这里分享了完整的代码:play.golang.org/p/Smm0BFgtNp,它可能会有所帮助
  • 我也不想为此目的使用ind,但如果我将其留空,则会出现“意外],期待表达式”错误,现在只是为了避免我通过它。我怎样才能做到这一点,以便数组自己获取索引?
  • 我用spotsArr[availableSpot.Uid] = []map[int64][]int{make(map[int64][]int)} 替换了spotsArr[availableSpot.Uid][ind] = make(map[int64][]int) 行,但我仍然面临错误。
猜你喜欢
  • 2013-06-06
  • 2020-07-26
  • 1970-01-01
  • 2019-01-01
  • 2010-10-14
  • 2012-06-05
  • 2013-07-27
相关资源
最近更新 更多