ZetCode

Golang slices.Delete

最后修改于 2025 年 4 月 20 日

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

slices.Delete 函数用于从切片中移除元素并返回修改后的切片。它是 Go 实验性 slices 包的一部分。

此函数有助于安全地移除元素而不造成内存泄漏。它会处理索引边界检查,并返回一个移除元素的新切片。

基本的 slices.Delete 示例

slices.Delete 最简单的用法是移除切片中的一个元素。我们指定要移除元素的开始和结束索引。

basic_delete.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    numbers := []int{1, 2, 3, 4, 5}
    
    // Remove element at index 2 (value 3)
    numbers = slices.Delete(numbers, 2, 3)
    
    fmt.Println("After deletion:", numbers)
}

我们创建一个数字切片,并移除索引为 2 的元素。该函数接收切片以及要删除的范围(从 2 到 3,不包含 3)。

移除多个元素

slices.Delete 可以移除一个范围内的元素。此示例从切片中移除三个连续的元素。

multiple_delete.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    letters := []string{"a", "b", "c", "d", "e", "f"}
    
    // Remove elements from index 1 to 4 (b, c, d)
    letters = slices.Delete(letters, 1, 4)
    
    fmt.Println("After deletion:", letters)
}

该函数从索引 1 开始,直到(但不包括)索引 4,移除其中的元素。结果切片包含 ["a", "e", "f"]。

处理结构体切片

我们可以将 slices.Delete 用于自定义结构体类型。此示例从 Person 结构体切片中移除一个人。

struct_delete.go
package main

import (
    "fmt"
    "slices"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 17},
    }
    
    // Remove Bob (index 1)
    people = slices.Delete(people, 1, 2)
    
    fmt.Println("Remaining people:", people)
}

该函数移除索引为 1 的元素(Bob)。切片被修改为只包含 Alice 和 Charlie。

边缘情况:空切片

slices.Delete 可以优雅地处理空切片。此示例展示了尝试从空切片中删除元素时的行为。

empty_slice.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    var empty []int
    
    // Try to delete from empty slice
    result := slices.Delete(empty, 0, 1)
    
    fmt.Println("Result:", result)
    fmt.Println("Length:", len(result))
}

该函数返回一个空切片而不会引发 panic。这使得它即使在输入可能为空时也能安全使用。

性能注意事项

对于大型切片,删除元素会对性能产生影响。此示例将对不同位置的删除进行基准测试。

performance.go
package main

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

func main() {
    largeSlice := make([]int, 1_000_000)
    for i := range largeSlice {
        largeSlice[i] = i
    }
    
    // Delete from start
    start := time.Now()
    _ = slices.Delete(largeSlice, 0, 1)
    fmt.Println("Delete from start:", time.Since(start))
    
    // Delete from middle
    start = time.Now()
    _ = slices.Delete(largeSlice, 500_000, 500_001)
    fmt.Println("Delete from middle:", time.Since(start))
    
    // Delete from end
    start = time.Now()
    _ = slices.Delete(largeSlice, 999_999, 1_000_000)
    fmt.Println("Delete from end:", time.Since(start))
}

从开头删除成本最高,因为它需要移动所有元素。从末尾删除速度最快,因为不需要移动任何元素。

实际示例:移除无效条目

这个实际示例从用户输入切片中移除了无效条目。我们从测量列表中过滤掉负数。

filter_invalid.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    measurements := []float64{1.2, -0.5, 3.4, -2.1, 5.6, -0.9}
    
    // Remove all negative measurements
    for i := 0; i < len(measurements); {
        if measurements[i] < 0 {
            measurements = slices.Delete(measurements, i, i+1)
        } else {
            i++
        }
    }
    
    fmt.Println("Valid measurements:", measurements)
}

我们遍历切片并移除负值。请注意,我们只在未删除元素时才递增索引,以处理元素移位的情况。

与其他切片操作结合使用

此示例展示了如何将 slices.Delete 与其他切片操作结合使用来实现更复杂的功能。

combined_operations.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    data := []int{10, 20, 30, 40, 50, 60, 70}
    
    // Find index of element to delete
    idx := slices.Index(data, 40)
    
    if idx != -1 {
        // Delete element and everything after it
        data = slices.Delete(data, idx, len(data))
    }
    
    fmt.Println("Result:", data)
}

我们首先使用 slices.Index 查找要删除元素的索引。然后,我们在一项操作中删除该元素及其之后的所有元素。

来源

Go 实验性切片包文档

本教程通过各种场景下移除元素的实际示例,讲解了 Go 中的 slices.Delete 函数。

作者

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

列出所有 Go 教程