最直接可靠的方式是用 for 循环遍历数组;Go 1.21+ 的 slices.Contains 仅支持切片,数组需显式转为 arr[:] 才能使用,且泛型函数因长度参数限制实用性有限。

用 for 循环遍历是最直接可靠的方式
Go 没有内置的 contains 函数(直到 Go 1.21 才在 slices 包里提供,但仅限切片,且不支持数组),所以对数组必须手动遍历。数组长度固定、类型明确,for 配合 == 或自定义比较逻辑最稳妥。
常见错误是误把数组当切片传给 slices.Contains,导致编译失败——因为 [3]int 和 []int 是完全不同的类型。
- 对基本类型(如
int、string)直接用==比较 - 对结构体或指针,需自行实现相等逻辑(比如逐字段比对或用
reflect.DeepEqual,但注意性能开销) - 若数组很大且查找频繁,考虑提前转成
map做 O(1) 查找,但要注意内存和初始化成本
slices.Contains 只适用于切片,不能直接用于数组
Go 1.21+ 引入了 slices 包,但它的 Contains 函数签名是 func Contains[S ~[]E, E comparable](s S, v E) bool,其中 S 必须是切片类型。数组无法隐式转换为切片,必须显式切片转换:
arr := [3]string{"a", "b", "c"}
found := slices.Contains(arr[:], "b") // ✅ 正确:arr[:] 转为 []string
// found := slices.Contains(arr, "b") // ❌ 编译错误:cannot use arr (variable of type [3]string) as []string value
注意:arr[:] 不会拷贝底层数组,只是创建新切片头,开销极小;但该切片仍受原数组生命周期约束。
自定义泛型函数能复用且类型安全
如果项目中多次需要查数组,写一个泛型函数比重复写 for 更清晰。利用 comparable 约束可覆盖大部分场景:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
func ContainsArray[T comparable](arr [N]T, v T) bool {
for _, item := range arr {
if item == v {
return true
}
}
return false
}
// 使用示例:
found := ContainsArray([3]int{1, 2, 3}, 2)
缺点是目前 Go 泛型不支持「任意长度数组」作为类型参数([N]T 中 N 必须是具体常量),所以每个不同长度的数组都需要单独实例化,实际中不如直接写循环灵活。
字符串数组查子串时别混淆 strings.Contains
遇到 []string 类型,容易下意识用 strings.Contains,但它只作用于单个 string,不是字符串集合。正确做法仍是遍历 + strings.Contains 或 ==:
-
strings.Contains("hello", "ll")✅ 判断子串 -
slices.Contains(myStrings, "target")✅ 判断元素是否存在(需先转切片) -
strings.Contains(myStrings, "target")❌ 编译失败:myStrings是[]string,不是string
数组维度和类型边界在 Go 里非常严格,稍不注意就会卡在类型转换上——尤其是从切片思维切换回数组时,[:] 这一步最容易被忽略。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










