ZetCode

Golang slices.Contains

最后修改于 2025 年 4 月 20 日

本教程将讲解如何在 Go 中使用 slices.Contains 函数。我们将通过实际示例介绍切片操作,演示如何检查元素。

slices.Contains 函数用于测试切片是否包含特定元素。它是 Go 实验性 slices 包的一部分。

此函数非常有用,可以避免编写手动循环来检查元素是否存在。如果找到元素,则返回 true,否则返回 false。

基本 slices.Contains 示例

slices.Contains 最简单的用法是检查数字是否存在于切片中。我们将切片和要搜索的目标值传递给它。

basic_contains.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    numbers := []int{1, 2, 3, 4, 5}
    
    hasThree := slices.Contains(numbers, 3)
    hasSix := slices.Contains(numbers, 6)
    
    fmt.Println("Contains 3:", hasThree)
    fmt.Println("Contains 6:", hasSix)
}

我们创建一个数字切片,并检查 3 和 6 的存在性。对于存在的 3,函数返回 true;对于不存在的 6,函数返回 false。

检查字符串是否存在

slices.Contains 可以用于字符串切片。此示例检查特定水果是否存在于切片中。

string_contains.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    fruits := []string{"apple", "banana", "cherry"}
    
    hasBanana := slices.Contains(fruits, "banana")
    hasOrange := slices.Contains(fruits, "orange")
    
    fmt.Println("Has banana:", hasBanana)
    fmt.Println("Has orange:", hasOrange)
}

该函数执行区分大小写的比较。Banana 被找到,而 orange 不存在于切片中。

使用结构体

对于自定义结构体类型,slices.Contains 使用深度相等性进行比较。此示例检查切片中是否存在特定的人。

struct_contains.go
package main

import (
    "fmt"
    "slices"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 17},
    }
    
    target := Person{"Bob", 30}
    hasBob := slices.Contains(people, target)
    
    fmt.Println("Contains Bob:", hasBob)
}

该函数会比较所有结构体字段。只有完全匹配(姓名和年龄都相同)才会返回 true。

检查多个值

我们可以将 slices.Contains 与循环结合使用来检查多个值。此示例验证是否所有必需的物品都存在。

multiple_values.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    inventory := []string{"sword", "shield", "potion"}
    required := []string{"sword", "potion"}
    
    allPresent := true
    for _, item := range required {
        if !slices.Contains(inventory, item) {
            allPresent = false
            break
        }
    }
    
    fmt.Println("All required items present:", allPresent)
}

我们遍历必需的物品并检查每一项。只有当所有物品都在库存中找到时,结果才为 true。

空切片行为

slices.Contains 对于空切片始终返回 false。此示例演示了这一行为。

empty_slice.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    var empty []string
    
    result := slices.Contains(empty, "anything")
    
    fmt.Println("Result for empty slice:", result)
}

空切片不包含任何元素。无论搜索值是什么,函数都返回 false。

性能注意事项

对于大型切片,slices.Contains 执行线性搜索。此示例对该操作进行了基准测试。

performance.go
package main

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

func main() {
    largeSlice := make([]int, 1_000_000)
    for i := range largeSlice {
        largeSlice[i] = i
    }
    
    // Search for first element
    start := time.Now()
    _ = slices.Contains(largeSlice, 0)
    fmt.Println("First element:", time.Since(start))
    
    // Search for last element
    start = time.Now()
    _ = slices.Contains(largeSlice, 999_999)
    fmt.Println("Last element:", time.Since(start))
    
    // Search for missing element
    start = time.Now()
    _ = slices.Contains(largeSlice, -1)
    fmt.Println("Missing element:", time.Since(start))
}

该函数按顺序扫描元素。最好情况是 O(1)(第一个元素),最坏情况是 O(n)(最后一个或不存在的元素)。

实际示例:用户验证

这个实际示例检查用户名是否存在于注册用户列表中。

user_validation.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    registeredUsers := []string{"alice", "bob", "charlie"}
    
    var username string
    fmt.Print("Enter username: ")
    fmt.Scanln(&username)
    
    if slices.Contains(registeredUsers, username) {
        fmt.Println("Welcome back,", username)
    } else {
        fmt.Println("Username not found")
    }
}

程序会提示输入用户名,并与注册列表进行比对。这展示了一个常见的实际应用场景。

来源

Go 实验性切片包文档

本教程通过实际示例,涵盖了 Go 中 slices.Contains 函数在各种场景下检查元素的使用方法。

作者

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

列出所有 Go 教程