'分割切片时,切片范围超出范围' -error

时间:2018-04-08 17:10:17

标签: go slice division

我想运行一堆goroutine来将大量的.csv文件插入到postgres数据库中。我将.csv文件读取到一个对象,然后尝试将对象分成10个部分。当文件数量可以精确地分割为10时,这种方法非常有效,但是当它不是panic: runtime error: slice bounds out of range时。

如果i + len(fis)/gophers返回浮点数,那将是明智的,但事实并非如此。当我使用Goland-IDE的debgging模式时,ii + len(fis)/gophers的结果都是完整的整数。

有关此错误发生原因的任何线索提示?我最感兴趣的原因是为什么会发生这种情况,但如果有人能提出除% - 运算符之外的其他解决方案,我也会感到好奇。

提前致谢!

编辑:我的印象是第一次迭代时返回错误(此时,根据调试器,ii + len(fis)/gophers都在len(fis)的范围内。目录中的文件数量是2568.事实证明错误发生在最后一次迭代上。感谢Berry指出这一点。

//Read files from download-folder
f, _ := os.Open(dlFolder)
fis, _ := f.Readdir(-1)
f.Close()

var wg sync.WaitGroup

gophers := 10

//Split slice of files into 10 chunks and run a goroutine for each of them
for i := 0; i < len(fis) ; i = i + len(fis)/gophers{

    wg.Add(1)

    xFiles := fis[i:i + len(fis)/gophers]
    go csvTSql(xFiles)

}

wg.Wait()

1 个答案:

答案 0 :(得分:3)

再次检查。如果i + len(fis)/gophers无法被len(fis)整除,gophers将不会受到约束。它将超过最后一次迭代的界限。

有很多方法可以解决此问题,例如检查i + len(fis)/gophers > len(fis) - 1是否重置,如果是,则重置值。您也可以使用math.Min来电。

chunk := int(math.Min(float64(i+len(fis)/gophers), float64(len(fis))))
xFiles := fis[i:chunk]