• 欢迎访问周知博客,每周记录新知识
  • 祝各位学得开心!!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

go过滤方案踩坑

工作技术 admin 4个月前 (01-11) 81次浏览 0个评论
        for _k, _v := range categoryData {
		if !CountryService.CheckCountryPass(currentCountryName) {
			categoryData = append(categoryData[:_k], categoryData[_k+1:]...)
		}
	}

最近写了这样的代码,报错: runtime error: slice bounds out of range [21:19]

来看看chatgpt的解说(一行没改):

这段代码看起来是用Go语言写的,其目的似乎是循环遍历一个名为`categoryData`的切片(Slice),并条件性地移除一些不符合通过`CheckCountryPass`函数指定条件的元素。但是,这种在迭代过程中直接修改切片的长度是不安全的,因为它可能会导致跳过某些元素或者出现索引越界错误。
问题在于每次从切片中移除一个元素后,所有后续元素的索引都会改变,但是循环的索引`_k`并没有相应的调整。以下是这个问题的细节:
– 当你移除`categoryData[_k]`时,所有在这个索引之后的元素都会向前移动一个位置。
– 这意味着原来位于`_k+1`位置的元素现在位于`_k`。
– 循环在下一次迭代时将增加`_k`的值,将跳过当前位于`_k`的元素,原因是它现在检查的是新的`_k+1`位置的元素。
此外,如果你试图访问`categoryData[_k+1:]`而`_k+1`恰好是`categoryData`的长度,你将得到一个空的切片。如果再对这个空切片追加,可能不会产生错误,但这不是好的做法。
为了安全地在迭代过程中删除切片中的元素,通常的做法是反向迭代切片或创建一个新切片来存储要保留的元素。
例如,可以按如下方式修改代码:

newCategoryData := make([]CategoryDataType, 0) // 假设CategoryDataType是具体的类型
for _k, _v := range categoryData {
    if CountryService.CheckCountryPass(currentCountryName) {
        newCategoryData = append(newCategoryData, _v)
    }
}
categoryData = newCategoryData // 替换原有的切片

上面的代码创建了一个新的空切片`newCategoryData`,然后将通过检查的元素添加到这个新切片中。最后,用新的`newCategoryData`替换掉原来的`categoryData`。这种方法不会修改正在迭代的切片,使得整个过程更安全、更容易理解。

chatgpt说得真好!学到了,以后要小心这个坑


周知博客, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:go过滤方案踩坑
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址