ZetCode

Go slices 包

最后修改日期:2024 年 4 月 15 日

在本文中,我们将展示如何在 Golang 中使用 slices 包。

一个切片是数组元素的一个动态大小、灵活的视图。切片可以在底层数组的边界内增长和收缩。切片不存储任何数据,它只描述数组的一部分。

slices 是一个标准的 Go 包,其中包含用于处理切片容器的有用函数。该包允许我们对元素进行排序、删除元素、搜索元素或检查元素是否存在。

删除元素

我们可以使用 slices.Deleteslices.DeleteFunc 删除元素。

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    words := []string{"sky", "pen", "book", "cup", "water", "war", "cloud"}
    fmt.Println(words)

    words = slices.Delete(words, 1, 2)
    fmt.Println(words)

    words = slices.Delete(words, 4, 6)
    fmt.Println(words)

    vals := []int{1, 2, -3, -4, 5, 6}

    vals = slices.DeleteFunc(vals, func(e int) bool {
        return e < 0
    })

    fmt.Println(vals)
}

该示例删除切片元素。

words = slices.Delete(words, 1, 2)

我们删除第二个元素。第二个索引是不包含在内的。

words = slices.Delete(words, 4, 6)

这行代码删除了索引为 4 和 5 的两个元素。

vals = slices.DeleteFunc(vals, func(e int) bool {
    return e < 0
})

DeleteFunc 会删除所有使函数返回 true 的元素。在我们的例子中,我们删除了所有负数。

$ go run main.go
[sky pen book cup water war cloud]
[sky book cup water war cloud]
[sky book cup water]
[1 2 5 6]

插入元素

slices.Insert 函数在指定的索引处插入一个或多个元素,并返回修改后的切片。

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {

    words := []string{"sky", "pen", "book", "cup", "war"}
    fmt.Println(words)

    words = slices.Insert(words, 0, "rock")
    fmt.Println(words)

    words = slices.Insert(words, len(words), "smart", "storm")
    fmt.Println(words)
}

该示例在切片开头插入一个单词,然后在末尾插入两个单词。

$ go run main.go
[sky pen book cup war]
[rock sky pen book cup war]
[rock sky pen book cup war smart storm]

检查元素是否存在

slice.Contains 检查提供的 `value` 是否存在于切片中。slices.ContainsFunc 检查是否存在满足函数提供的给定条件的元素。

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {

    words := []string{"sky", "pen", "book", "cup", "war",
        "water", "cloud"}
    fmt.Println(words)

    word := "cloud"

    if slices.Contains(words, word) {
        fmt.Printf("the slice contains the word %s\n", word)
    } else {
        fmt.Printf("the slice does not contain the word %s\n", word)
    }

    vals := []int{2, 5, 8, 12}

    if slices.ContainsFunc(vals, func(e int) bool {

        return e%2 == 0
    }) {
        fmt.Println("the slice contains even value")

    } else {
        fmt.Println("the slice does not contain an even value")
    }
}

该示例检查 `words` 切片是否包含 `cloud` 字符串,以及 `vals` 切片是否包含偶数。

$ go run main.go
the slice contains the word cloud
the slice contains even value

比较元素

slices.Compare 使用 `cmp.Compare` 对每一对元素进行比较,以比较 s1 和 s2 的元素。如果 s1 == s2,则结果为 0;如果 s1 < s2,则结果为 -1;如果 s1 > s2,则结果为 +1。

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {

    vals := []int{1, 2, 3, 4, 5}
    vals2 := []int{1, 2, 3, 4, 5}
    vals3 := []int{2, 1, 5, 4, 3}

    if slices.Compare(vals, vals2) == 0 {
        fmt.Println("vals and vals2 are equal")
    } else {
        fmt.Println("vals and vals2 are not equal")
    }

    if slices.Compare(vals, vals3) == 0 {
        fmt.Println("vals and vals3 are equal")
    } else {
        fmt.Println("vals and vals3 are not equal")
    }
}

在示例中,我们将 `vals` 的元素与 `vals2` 和 `vals3` 进行比较。

$ go run main.go
vals and vals2 are equal
vals and vals3 are not equal

在本文中,我们处理了 Golang 中的切片。

排序元素

slices.Sort 函数以升序对任何有序类型的切片进行排序。排序是就地进行的。

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {

    vals := []int{1, 2, 0, -3, -2, -1, 3, 4}
    fmt.Println(vals)

    slices.Sort(vals)
    fmt.Println(vals)

    words := []string{"sky", "pen", "book", "cup", "atom", "water",
        "war", "cloud", "storm", "forest", "dandelion"}
    fmt.Println(words)

    slices.Sort(words)
    fmt.Println(words)
}

在示例中,我们将整数和字符串切片按升序排序。

$ go run main.go
[1 2 0 -3 -2 -1 3 4]
[-3 -2 -1 0 1 2 3 4]
[sky pen book cup atom water war cloud storm forest dandelion]
[atom book cloud cup dandelion forest pen sky storm war water]

要按降序排序值,我们先用 slices.Sort 对值进行排序,然后调用 slices.Reverse

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {

    vals := []int{1, 2, 0, -3, -2, -1, 3, 4}
    fmt.Println(vals)

    slices.Sort(vals)
    slices.Reverse(vals)
    fmt.Println(vals)

    words := []string{"sky", "pen", "book", "cup", "atom", "water",
        "war", "cloud", "storm", "forest", "dandelion"}
    fmt.Println(words)

    slices.Sort(words)
    slices.Reverse(words)
    fmt.Println(words)
}

slices.Reverse 会就地反转切片中的元素。

$ go run main.go
[1 2 0 -3 -2 -1 3 4]
[4 3 2 1 0 -1 -2 -3]
[sky pen book cup atom water war cloud storm forest dandelion]
[water war storm sky pen forest dandelion cup cloud book atom]

可以使用 slices.SortFunc 实现自定义排序。

main.go
package main

import (
    "cmp"
    "fmt"
    "slices"
)

func main() {

    words := []string{"a", "book", "unforgettable", "cup", "waterfall",
        "unrealistic", "whisper", "storm", "irreversible", "by", "stronghold",
        "forest", "tomorrow"}

    slices.SortFunc(words, func(e1 string, e2 string) int {

        return cmp.Compare(len(e1), len(e2))
    })

    for _, word := range words {

        fmt.Println(word)
    }

    slices.SortFunc(words, func(e1 string, e2 string) int {

        return cmp.Compare(len(e2), len(e1))
    })

    for _, word := range words {

        fmt.Println(word)
    }
}

该示例按长度对单词进行排序。

slices.SortFunc(words, func(e1 string, e2 string) int {

    return cmp.Compare(len(e1), len(e2))
})

slices.SortFunc 根据 `cmp` 函数确定的升序对切片进行排序。

$ go run main.go
a
by
cup
book
storm
forest
whisper
tomorrow
waterfall
stronghold
unrealistic
irreversible
unforgettable
unforgettable
irreversible
unrealistic
stronghold
waterfall
tomorrow
whisper
forest
storm
book
cup
by
a

Compat 函数

slices.Compat 将连续相同的元素替换为单个副本。该功能类似于 Unix 中的 `uniq` 命令。

main.go
package main

import (
    "fmt"
    "slices"
)

func main() {

    words := []string{"sky", "pen", "book", "cup", "war",
        "water", "war", "cloud", "pen"}
    fmt.Println(words)

    words = slices.Compact(words)
    fmt.Println(words)

    slices.Sort(words)
    words = slices.Compact(words)
    fmt.Println(words)
}

为了从切片中删除重复项,我们需要先对其进行排序,然后调用 slices.Compact

$ go run main.go
[sky pen book cup war water war cloud pen]
[sky pen book cup war water war cloud pen]
[book cloud cup pen sky war water]

来源

Go slices 包 - 参考

在本文中,我们处理了 Golang 中的 slices 包。

作者

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

列出所有 Go 教程