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` 函数的使用,重点是在切片中查找具有自定义条件的元素。