ZetCode

Golang slices.Equal

最后修改于 2025 年 4 月 20 日

本教程将讲解如何在 Go 中使用 slices.Equal 函数。我们将通过实际示例介绍切片比较和相等性检查。

slices.Equal 函数用于比较两个切片是否相等。它会检查两个切片的长度是否相同,并且元素是否以相同的顺序排列且相等。

此函数非常适合比较数据集合,而无需编写手动循环。它适用于 Go 中的任何可比较类型(支持 == 运算符的类型)。

基本 slices.Equal 示例

slices.Equal 最简单的用法是比较两个整数切片。仅当两个切片的长度和内容完全相同时,该函数才返回 true。

basic_equal.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    slice1 := []int{1, 2, 3}
    slice2 := []int{1, 2, 3}
    slice3 := []int{1, 2, 4}
    
    fmt.Println("slice1 == slice2:", slices.Equal(slice1, slice2))
    fmt.Println("slice1 == slice3:", slices.Equal(slice1, slice3))
}

我们创建了三个切片,其中两个是相同的。该函数能够正确识别相等和不相等的切片。比较对长度和元素都很敏感。

比较字符串切片

slices.Equal 同样适用于字符串切片。此示例比较了两个字符串切片是否相等。

string_equal.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    fruits1 := []string{"apple", "banana", "cherry"}
    fruits2 := []string{"apple", "banana", "cherry"}
    fruits3 := []string{"Apple", "Banana", "Cherry"}
    
    fmt.Println("fruits1 == fruits2:", slices.Equal(fruits1, fruits2))
    fmt.Println("fruits1 == fruits3:", slices.Equal(fruits1, fruits3))
}

Go 中的字符串比较是区分大小写的。即使字符串看起来相似,对于大小写不同的字符串,该函数也会返回 false。

比较结构体切片

如果结构体字段是可比较的,我们可以比较结构体切片。此示例展示了结构体切片的比较。

struct_equal.go
package main

import (
    "fmt"
    "slices"
)

type Point struct {
    X, Y int
}

func main() {
    points1 := []Point{{1, 2}, {3, 4}}
    points2 := []Point{{1, 2}, {3, 4}}
    points3 := []Point{{1, 2}, {3, 5}}
    
    fmt.Println("points1 == points2:", slices.Equal(points1, points2))
    fmt.Println("points1 == points3:", slices.Equal(points1, points3))
}

该函数会比较每个结构体元素的全部字段。要使切片被视为相等,所有字段都必须相等。

比较不同长度的切片

slices.Equal 会立即对不同长度的切片返回 false,而不进行元素比较。此示例演示了这种行为。

length_equal.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    short := []int{1, 2, 3}
    long := []int{1, 2, 3, 4}
    
    fmt.Println("Different length slices:", slices.Equal(short, long))
    
    samePrefix := []int{1, 2, 3, 0}
    fmt.Println("Same prefix slices:", slices.Equal(short, samePrefix[:3]))
}

即使第一个元素匹配,不同的长度也会导致切片不相等。为了提高效率,该函数会在比较元素之前先检查长度。

比较空切片

slices.Equal 将空切片视为相等。此示例显示了各种空切片比较。

empty_equal.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    empty1 := []int{}
    empty2 := make([]int, 0)
    var empty3 []int
    
    fmt.Println("empty1 == empty2:", slices.Equal(empty1, empty2))
    fmt.Println("empty1 == empty3:", slices.Equal(empty1, empty3))
    fmt.Println("empty1 == nil:", slices.Equal(empty1, nil))
}

所有空切片都相等,无论它们是如何创建的。该函数将 nil 切片视为与空切片相等。

比较具有不同容量的切片

容量不会影响相等性比较。此示例表明,对于相等性,只有长度和元素才重要。

capacity_equal.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    slice1 := make([]int, 3, 10)
    slice2 := make([]int, 3, 5)
    
    for i := 0; i < 3; i++ {
        slice1[i] = i + 1
        slice2[i] = i + 1
    }
    
    fmt.Println("Different capacity slices:", slices.Equal(slice1, slice2))
    fmt.Println("Capacities:", cap(slice1), cap(slice2))
}

尽管容量不同,但由于长度和元素匹配,切片仍然相等。容量与相等性比较无关。

实际示例:测试函数输出

这个实际示例使用 slices.Equal 来测试一个返回切片的函数。这是单元测试中的一个常见用例。

testing_equal.go
package main

import (
    "fmt"
    "slices"
    "strings"
)

func SplitAndTrim(s string) []string {
    parts := strings.Split(s, ",")
    for i := range parts {
        parts[i] = strings.TrimSpace(parts[i])
    }
    return parts
}

func main() {
    input := "apple, banana, cherry"
    expected := []string{"apple", "banana", "cherry"}
    
    result := SplitAndTrim(input)
    
    if slices.Equal(result, expected) {
        fmt.Println("Test passed!")
    } else {
        fmt.Println("Test failed. Got:", result)
    }
}

我们将函数输出与预期结果进行比较。这种模式对于在测试用例中验证返回切片的函数很有用。

来源

Go 实验性切片包文档

本教程通过各种场景下的切片比较实际示例,涵盖了 Go 中的 slices.Equal 函数。

作者

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

列出所有 Go 教程