ZetCode

Golang maps.All

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在 Go 中使用 maps.All 函数。我们将通过实际示例涵盖 map 操作和条件检查。

maps.All 函数用于测试 map 中的所有键值对是否都满足给定条件。它是 Go 实验性 maps 包的一部分。

此函数可用于验证数据或检查 map 中所有条目的属性。只有当所有条目都通过测试时,它才返回 true。

基本 maps.All 示例

maps.All 最简单的用法是检查 map 中的所有值是否都为正数。我们为键值对定义一个测试函数。

basic_all.go
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。

key_value_check.go
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 中的所有产品是否都有库存。

custom_types.go
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。

组合多个条件

可以在测试函数中组合复杂的条件。此示例检查所有值是否为偶数,并且键是否为大写。

combined_conditions.go
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。

empty_map.go
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,测试函数的性能很重要。此示例对不同的方法进行了基准测试。

performance.go
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 验证配置设置。我们检查所有配置值是否都满足要求。

config_validation.go
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")
    }
}

我们使用特定规则验证不同的配置参数。类型转换和验证的组合展示了实际用法。

来源

Go 实验性 maps 包文档

本教程通过在各种场景下检查 map 条目条件方面的实际示例,介绍了 Go 中的 maps.All 函数。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程