ZetCode

Golang 切片比较

最后修改于 2025 年 4 月 20 日

本教程解释了如何在 Go 中使用 slices.Compare 函数。我们将通过实际示例涵盖切片比较操作。

slices.Compare 函数按字典顺序比较两个切片。如果切片相等,则返回 0;如果第一个切片“小于”,则返回 -1;如果第一个切片“大于”,则返回 1。

此函数对于排序、测试相等性和排序操作很有用。它按顺序比较元素,直到找到差异或到达末尾。

基本 slices.Compare 示例

slices.Compare 最简单的用法是检查两个整数切片是否相等。当切片具有相同的元素时,该函数返回 0。

basic_compare.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{1, 2, 3}
    
    result := slices.Compare(s1, s2)
    fmt.Println("Comparison result:", result)
}

我们创建了两个相同的整数切片并比较它们。输出为 0,表示切片逐个元素相等。

比较不同的切片

当切片不同时,slices.Compare 返回 -1 或 1。此示例显示了不同元素的切片比较。

different_slices.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{1, 3, 2}
    
    result1 := slices.Compare(s1, s2)
    result2 := slices.Compare(s2, s1)
    
    fmt.Println("s1 vs s2:", result1)
    fmt.Println("s2 vs s1:", result2)
}

第一次比较返回 -1,因为索引 1 处的 2 小于 3。反向比较返回 1,表明顺序很重要。

比较字符串切片

我们可以将 slices.Compare 与字符串切片一起使用。比较是字典顺序的,就像字典顺序一样。

string_compare.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    words1 := []string{"apple", "banana"}
    words2 := []string{"apple", "cherry"}
    
    result := slices.Compare(words1, words2)
    fmt.Println("Comparison result:", result)
}

该函数在索引 1 处比较“banana”和“cherry”。由于“banana”在字母顺序上先于“cherry”,因此返回 -1。

比较不同长度的切片

当比较不同长度的切片时,如果所有元素都匹配到较短的长度,则较短的切片被视为“小于”。

different_lengths.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    s1 := []int{1, 2, 3}
    s2 := []int{1, 2}
    
    result1 := slices.Compare(s1, s2)
    result2 := slices.Compare(s2, s1)
    
    fmt.Println("Longer vs shorter:", result1)
    fmt.Println("Shorter vs longer:", result2)
}

第一次比较返回 1,因为 s1 比 s2 长。第二次比较返回 -1,因为 s2 比 s1 短。元素匹配到较短的长度。

将 Compare 用于结构体切片

slices.Compare 可与任何可比较的类型一起使用,包括结构体。比较是按声明顺序逐个字段进行的。

struct_compare.go
package main

import (
    "fmt"
    "slices"
)

type Point struct {
    X, Y int
}

func main() {
    p1 := []Point{{1, 2}, {3, 4}}
    p2 := []Point{{1, 2}, {3, 5}}
    
    result := slices.Compare(p1, p2)
    fmt.Println("Comparison result:", result)
}

该函数首先按 X 比较 Point 结构体,然后按 Y 比较。在索引 1 处,Y 值 4 和 5 不同,因此返回 -1,因为 4 小于 5。

实际示例:版本比较

这个实际示例比较了表示为整数切片的版本号。它演示了 slices.Compare 的实际用法。

version_compare.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    v1 := []int{1, 18, 0}
    v2 := []int{1, 19, 0}
    
    result := slices.Compare(v1, v2)
    
    switch result {
    case -1:
        fmt.Println("v1 is older than v2")
    case 0:
        fmt.Println("Versions are equal")
    case 1:
        fmt.Println("v1 is newer than v2")
    }
}

我们比较了表示为整数切片的两个版本号(1.18.0 和 1.19.0)。输出显示 v1 比 v2 旧,因为 18 对比 19。

性能注意事项

对于大型切片,slices.Compare 的性能与切片长度呈线性关系。此示例对比较操作进行了基准测试。

performance.go
package main

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

func main() {
    large1 := make([]int, 1_000_000)
    large2 := make([]int, 1_000_000)
    
    // Equal slices
    start := time.Now()
    _ = slices.Compare(large1, large2)
    fmt.Println("Equal slices:", time.Since(start))
    
    // Different at start
    large2[0] = 1
    start = time.Now()
    _ = slices.Compare(large1, large2)
    fmt.Println("Different first element:", time.Since(start))
    
    // Different at end
    large2[0] = 0
    large2[999_999] = 1
    start = time.Now()
    _ = slices.Compare(large1, large2)
    fmt.Println("Different last element:", time.Since(start))
}

该函数在第一个差异处停止,因此性能取决于第一个不匹配发生的位置。早期差异的检测速度更快。

来源

Go 实验性切片包文档

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

作者

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

列出所有 Go 教程