Golang maps.All
最后修改于 2025 年 4 月 20 日
本教程将介绍如何在 Go 中使用 maps.All 函数。我们将通过实际示例涵盖 map 操作和条件检查。
maps.All 函数用于测试 map 中的所有键值对是否都满足给定条件。它是 Go 实验性 maps 包的一部分。
此函数可用于验证数据或检查 map 中所有条目的属性。只有当所有条目都通过测试时,它才返回 true。
基本 maps.All 示例
maps.All 最简单的用法是检查 map 中的所有值是否都为正数。我们为键值对定义一个测试函数。
package main
import (
"fmt"
"maps"
)
func main() {
scores := map[string]int{
"Alice": 85,
"Bob": 92,
"Carol": 78,
}
allPositive := maps.All(scores, func(k string, v int) bool {
return v > 0
})
fmt.Println("All scores positive:", allPositive)
}
我们创建一个分数 map,并检查所有值是否都大于零。匿名函数为每个键值对定义了我们的条件。
同时检查键和值
maps.All 可以验证键和值的所有属性。此示例检查所有键是否以 'A' 开头,并且值是否大于 80。
package main
import (
"fmt"
"maps"
"strings"
)
func main() {
grades := map[string]int{
"Alice": 85,
"Amy": 92,
"Anna": 78,
}
allValid := maps.All(grades, func(k string, v int) bool {
return strings.HasPrefix(k, "A") && v > 80
})
fmt.Println("All names start with A and grades > 80:", allValid)
}
测试函数同时检查键前缀和值。由于 Anna 的分数是 78,因此函数返回 false。
使用自定义类型
我们可以将 maps.All 与自定义值类型一起使用。此示例检查 map 中的所有产品是否都有库存。
package main
import (
"fmt"
"maps"
)
type Product struct {
Name string
InStock bool
Quantity int
}
func main() {
inventory := map[string]Product{
"p1": {"Laptop", true, 10},
"p2": {"Mouse", false, 0},
"p3": {"Keyboard", true, 15},
}
allInStock := maps.All(inventory, func(k string, p Product) bool {
return p.InStock
})
fmt.Println("All products in stock:", allInStock)
}
该函数检查每个产品的 InStock 字段。由于鼠标缺货,结果为 false。
组合多个条件
可以在测试函数中组合复杂的条件。此示例检查所有值是否为偶数,并且键是否为大写。
package main
import (
"fmt"
"maps"
"strings"
"unicode"
)
func main() {
data := map[string]int{
"A": 2,
"B": 4,
"C": 6,
}
allValid := maps.All(data, func(k string, v int) bool {
return v%2 == 0 &&
strings.ToUpper(k) == k &&
len(k) == 1 &&
unicode.IsLetter(rune(k[0]))
})
fmt.Println("All conditions met:", allValid)
}
条件使用逻辑 AND 组合了多个检查。所有条目都满足所有条件,因此结果为 true。
空映射行为
maps.All 对空 map 有特殊行为。此示例演示了它如何始终对空 map 返回 true。
package main
import (
"fmt"
"maps"
)
func main() {
var empty map[string]int
result := maps.All(empty, func(k string, v int) bool {
return false // Condition doesn't matter
})
fmt.Println("Result for empty map:", result)
}
由于没有要检查的条目,函数空虚地返回 true。此行为遵循数学逻辑中的全称量化。
性能注意事项
对于大型 map,测试函数的性能很重要。此示例对不同的方法进行了基准测试。
package main
import (
"fmt"
"maps"
"time"
)
func main() {
largeMap := make(map[int]int, 1_000_000)
for i := 0; i < 1_000_000; i++ {
largeMap[i] = i
}
// Simple condition
start := time.Now()
_ = maps.All(largeMap, func(k, v int) bool {
return v >= 0
})
fmt.Println("Simple condition:", time.Since(start))
// Complex condition
start = time.Now()
_ = maps.All(largeMap, func(k, v int) bool {
return v >= 0 && k%2 == 0 && v < 1_000_000
})
fmt.Println("Complex condition:", time.Since(start))
}
执行时间取决于条件的复杂性和 map 的大小。maps.All 为了效率会在第一个不满足条件的条目处停止。
实际示例:配置验证
此实际示例使用 maps.All 验证配置设置。我们检查所有配置值是否都满足要求。
package main
import (
"fmt"
"maps"
"strconv"
)
func main() {
config := map[string]string{
"timeout": "30",
"retries": "3",
"log_level": "debug",
}
allValid := maps.All(config, func(k, v string) bool {
switch k {
case "timeout":
n, err := strconv.Atoi(v)
return err == nil && n > 0
case "retries":
n, err := strconv.Atoi(v)
return err == nil && n >= 0 && n <= 5
case "log_level":
return v == "info" || v == "debug" || v == "error"
default:
return false
}
})
if allValid {
fmt.Println("All configuration values are valid")
} else {
fmt.Println("Some configuration values are invalid")
}
}
我们使用特定规则验证不同的配置参数。类型转换和验证的组合展示了实际用法。
来源
本教程通过在各种场景下检查 map 条目条件方面的实际示例,介绍了 Go 中的 maps.All 函数。