'Slice bounds out of range'-分割切片时出错
'Slice bounds out of range'-error when splitting a slice
我想 运行 一堆 goroutines 将大量的 .csv 文件插入到 postgres 数据库中。我将 .csv 文件读取到一个对象,然后尝试将该对象分成 10 个部分。当文件数量正好可以被 10 整除时,这非常有效,但如果不是,我会得到 panic: runtime error: slice bounds out of range
。
如果 i + len(fis)/gophers
返回一个浮点数,这将是明智的,但事实并非如此。当我使用 Goland-IDE 的 debgging-mode 时,i
和 i + len(fis)/gophers
的结果都是完整的整数。
关于为什么会出现此错误的任何线索?我最感兴趣的是为什么会发生这种情况背后的理论,但也很好奇是否有人可以提出除使用 %
-运算符之外的解决方案。
提前致谢!
编辑:我的印象是第一次迭代时返回错误(此时,根据调试器,i
和 i + len(fis)/gophers
都在 [=19 的范围内=]。目录中的文件数量是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()
再次检查。如果 len(fis)
不能被 gophers
整除,i + 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]
我想 运行 一堆 goroutines 将大量的 .csv 文件插入到 postgres 数据库中。我将 .csv 文件读取到一个对象,然后尝试将该对象分成 10 个部分。当文件数量正好可以被 10 整除时,这非常有效,但如果不是,我会得到 panic: runtime error: slice bounds out of range
。
如果 i + len(fis)/gophers
返回一个浮点数,这将是明智的,但事实并非如此。当我使用 Goland-IDE 的 debgging-mode 时,i
和 i + len(fis)/gophers
的结果都是完整的整数。
关于为什么会出现此错误的任何线索?我最感兴趣的是为什么会发生这种情况背后的理论,但也很好奇是否有人可以提出除使用 %
-运算符之外的解决方案。
提前致谢!
编辑:我的印象是第一次迭代时返回错误(此时,根据调试器,i
和 i + len(fis)/gophers
都在 [=19 的范围内=]。目录中的文件数量是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()
再次检查。如果 len(fis)
不能被 gophers
整除,i + 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]