在 Go 中,如何对任何类型的 slice/array/string 进行分区?

In Go, how can I partition a slice/array/string of any type?

Guava 有一个 generic partition method 由于 Go 缺乏泛型而不能直接在 Go 中实现。有解决办法吗?

gopart 库解决了这个问题。它允许对任何类型的 Go 中可索引的任何内容进行分区。

for idxRange := range gopart.Partition(len(bigList), partitionSize) {
        bulkOperation(bigList[idxRange.Low:idxRange.High])
}

Full Executable Example

我找到这个问题和答案是因为在我创建已经存在的东西之前我需要相同的解决方案。

但是,我确实不喜欢该解决方案的性能,因此我创建了一个实现更快、更灵活的程序包。

为了提高速度,我没有使用通道,而是使用了一个传递给函数作为结果回调的函数。我还添加了使用切片和接口的实现,以及一个通道来比较所有这些方法的性能,并让用户可以灵活地使用他们需要的方法。

为了防止其他人也需要创建自己的实现,我在以下位置公开了它 url:https://github.com/crosscode-nl/partition

根据代码的基准测试,基于通道的解决方案比 func 版本慢。

BenchmarkToChan100-4           50000         25862 ns/op
BenchmarkToChan10-4           300000          4939 ns/op
BenchmarkToChan0-4            500000          2727 ns/op
BenchmarkToFunc100-4         5000000           230 ns/op
BenchmarkToFunc10-4         30000000            46.5 ns/op
BenchmarkToFunc0-4          100000000           14.6 ns/op

用法示例:

a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
partition.ToFunc(len(a), 5, func(l int, h int) {
    fmt.Printf("Part: %v\n", a[l:h])
})
// Output:
// Part: [1 2 3 4 5]
// Part: [6 7 8 9]

有关详细信息,请参阅存储库中的基准。