ZetCode

Golang slices.Chunk

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在 Go 中使用 slices.Chunk 函数。我们将通过实际的切片分割示例来讲解切片操作。

slices.Chunk 函数将一个切片分割成指定大小的更小的块。它是 Go 实验性 slices 包的一部分。

此函数对于批量处理、分页或并行处理数据非常有用。它返回一个包含这些块的切片(即切片中的切片)。

基本的 slices.Chunk 示例

slices.Chunk 最简单的用法是将一个切片分割成大小相等的块。这里我们将一个包含 6 个数字的切片分割成大小为 2 的块。

basic_chunk.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    numbers := []int{1, 2, 3, 4, 5, 6}
    chunks := slices.Chunk(numbers, 2)
    
    fmt.Println("Original slice:", numbers)
    fmt.Println("Chunks:", chunks)
}

我们创建了一个数字切片,并将其分割成每块 2 个元素。该函数返回一个包含三个较小切片的切片。

不均匀的块大小

当切片长度不能被块大小整除时,最后一个块会比较小。此示例演示了这种行为。

uneven_chunks.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    letters := []string{"a", "b", "c", "d", "e"}
    chunks := slices.Chunk(letters, 2)
    
    fmt.Println("Original slice:", letters)
    fmt.Println("Chunks:", chunks)
}

该切片有 5 个元素,因此按 2 分块会创建 3 个块。最后一个块只包含一个元素。

块大小大于切片

如果块大小超过切片长度,结果将包含一个包含所有元素的块。此示例展示了这种边缘情况。

large_chunk.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    data := []float64{1.1, 2.2, 3.3}
    chunks := slices.Chunk(data, 5)
    
    fmt.Println("Original slice:", data)
    fmt.Println("Chunks:", chunks)
}

块大小 5 大于我们 3 个元素的切片。该函数返回一个包含所有元素的单个块。

使用结构体

我们可以将 slices.Chunk 与自定义结构体类型一起使用。此示例将 Person 结构体切片进行分块。

struct_chunk.go
package main

import (
    "fmt"
    "slices"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 17},
        {"Diana", 22},
    }
    
    chunks := slices.Chunk(people, 2)
    
    fmt.Println("People chunks:")
    for i, chunk := range chunks {
        fmt.Printf("Chunk %d: %v\n", i+1, chunk)
    }
}

Person 结构体切片被分成大小为 2 的块。每个块都保留原始的结构体类型和数据。

空切片行为

slices.Chunk 能很好地处理空切片。此示例展示了分割空切片时的结果。

empty_slice.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    var empty []int
    chunks := slices.Chunk(empty, 3)
    
    fmt.Println("Empty slice chunks:", chunks)
    fmt.Println("Number of chunks:", len(chunks))
}

分割空切片会返回一个空的切片(切片中的切片)。这种行为与数学预期一致。

实际示例:批量处理

此实际示例演示了如何将块用于批量处理。我们分批处理数据,以避免使系统过载。

batch_processing.go
package main

import (
    "fmt"
    "slices"
    "time"
)

func processBatch(batch []int) {
    fmt.Println("Processing batch:", batch)
    time.Sleep(500 * time.Millisecond)
}

func main() {
    data := make([]int, 10)
    for i := range data {
        data[i] = i + 1
    }
    
    chunks := slices.Chunk(data, 3)
    
    for _, batch := range chunks {
        processBatch(batch)
    }
}

我们创建了一个包含 10 个数字的切片,并将其分割成大小为 3 的块。然后,每个块都通过模拟延迟单独处理。

性能注意事项

对于大型切片,分块可能会占用大量内存。此示例使用不同的块大小对分块性能进行基准测试。

performance.go
package main

import (
    "fmt"
    "slices"
    "time"
)

func main() {
    largeSlice := make([]int, 1_000_000)
    for i := range largeSlice {
        largeSlice[i] = i
    }
    
    sizes := []int{10, 100, 1000, 10000}
    
    for _, size := range sizes {
        start := time.Now()
        chunks := slices.Chunk(largeSlice, size)
        elapsed := time.Since(start)
        
        fmt.Printf("Chunk size %6d: %d chunks, time %v\n",
            size, len(chunks), elapsed)
    }
}

执行时间取决于块大小和切片长度。较小的块意味着更多的内存分配,但可能更适合并行处理。

来源

Go 实验性切片包文档

本教程通过实际的切片分割示例,介绍了 Go 中的 slices.Chunk 函数,该函数可将切片分割成更小的块,以满足各种用例的需求。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程