Golang slices.IndexFunc
最后修改于 2025 年 4 月 20 日
本教程将介绍如何在 Go 中使用 `slices.IndexFunc` 函数。我们将通过实际示例涵盖切片操作,重点是查找元素。
`slices.IndexFunc` 函数在切片中搜索满足给定条件的第一个元素。它返回第一个匹配项的索引。
如果没有元素满足条件,它将返回 -1。此函数对于查找任何类型切片中的自定义元素非常有用。
基本的 slices.IndexFunc 示例
`slices.IndexFunc` 最简单的用法是查找切片中的第一个负数。我们定义一个测试函数来检查每个元素。
package main import ( "fmt" "slices" ) func main() { numbers := []int{1, 2, -3, 4, 5} idx := slices.IndexFunc(numbers, func(n int) bool { return n < 0 }) fmt.Println("First negative at index:", idx) }
我们搜索第一个小于零的数字。该函数返回索引 2,即 -3 所在的位置。匿名函数定义了我们的搜索条件。
查找具有特定属性的字符串
`slices.IndexFunc` 可以查找具有特定特征的字符串。此示例查找以“b”开头的第一个字符串。
package main import ( "fmt" "slices" "strings" ) func main() { words := []string{"apple", "banana", "cherry", "blueberry"} idx := slices.IndexFunc(words, func(s string) bool { return strings.HasPrefix(s, "b") }) fmt.Println("First 'b' word at index:", idx) }
测试函数使用 `strings.HasPrefix` 来检查每个字符串。它返回索引 1,即找到“banana”的位置,这是第一个匹配的元素。
搜索结构体切片
我们可以将 `slices.IndexFunc` 与自定义结构体类型一起使用。此示例查找切片中第一个 18 岁以下的人。
package main import ( "fmt" "slices" ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 30}, {"Charlie", 17}, {"Dave", 16}, } idx := slices.IndexFunc(people, func(p Person) bool { return p.Age < 18 }) fmt.Println("First minor at index:", idx) }
该函数检查每个人的年龄字段。它返回索引 2,即找到 Charlie 的位置,尽管 Dave 也未满 18 岁。
不区分大小写的字符串搜索
此示例演示了使用 `IndexFunc` 进行不区分大小写的搜索。我们查找“go”的第一个出现,不区分大小写。
package main import ( "fmt" "slices" "strings" ) func main() { langs := []string{"Python", "Go", "Rust", "GO", "Java"} idx := slices.IndexFunc(langs, func(s string) bool { return strings.EqualFold(s, "go") }) fmt.Println("First 'go' at index:", idx) }
`strings.EqualFold` 执行不区分大小写的比较。该函数返回索引 1,即找到“Go”的位置,忽略了稍后索引 3 处的“GO”。
查找具有多个条件的元素
可以在测试函数中组合复杂条件。此示例查找第一个大于 10 的偶数。
package main import ( "fmt" "slices" ) func main() { numbers := []int{5, 8, 12, 7, 14, 9} idx := slices.IndexFunc(numbers, func(n int) bool { return n > 10 && n%2 == 0 }) fmt.Println("First even >10 at index:", idx) }
该条件使用逻辑 AND 组合了两个检查。它返回索引 2,即找到 12 的位置,这是第一个满足两个条件的数字。
处理无匹配项
当没有元素满足条件时,`IndexFunc` 返回 -1。此示例演示了如何处理无匹配项的情况。
package main import ( "fmt" "slices" ) func main() { numbers := []int{1, 3, 5, 7, 9} idx := slices.IndexFunc(numbers, func(n int) bool { return n%2 == 0 }) if idx == -1 { fmt.Println("No even numbers found") } else { fmt.Println("First even at index:", idx) } }
由于切片只包含奇数,因此函数返回 -1。我们检查此值以正确处理无匹配项的情况。
实际示例:查找可用端口
这个实际示例使用 `IndexFunc` 来查找已使用端口列表中第一个可用的端口。
package main import ( "fmt" "slices" ) func main() { usedPorts := []int{80, 443, 8080, 3000, 8000} availablePorts := []int{3000, 4000, 5000, 8080, 9000} idx := slices.IndexFunc(availablePorts, func(p int) bool { return !slices.Contains(usedPorts, p) }) if idx != -1 { fmt.Printf("First available port: %d at index %d\n", availablePorts[idx], idx) } else { fmt.Println("No available ports found") } }
我们在 `availablePorts` 中搜索第一个不在 `usedPorts` 中的端口。函数返回索引 1,即端口 4000 被发现为可用。
来源
本教程通过实际示例,介绍了 Go 中 `slices.IndexFunc` 函数的使用,重点是在切片中查找具有自定义条件的元素。