Golang maps.DeleteFunc
最后修改于 2025 年 4 月 20 日
本教程将介绍如何在 Go 中使用 maps.DeleteFunc 函数。我们将通过条件删除的实际示例来讲解 map 操作。
maps.DeleteFunc 函数从 map 中移除满足给定条件的键值对。它是 Go 实验性 maps 包的一部分。
此函数可用于基于复杂条件选择性地删除元素。它会就地修改 map,并且不返回新的 map。
基本的 maps.DeleteFunc 示例
maps.DeleteFunc 最简单的用法是删除所有值为负数的条目。我们为删除条件定义了一个测试函数。
package main
import (
"fmt"
"maps"
)
func main() {
m := map[string]int{
"a": 1,
"b": -2,
"c": 3,
"d": -4,
}
maps.DeleteFunc(m, func(k string, v int) bool {
return v < 0
})
fmt.Println("Map after deletion:", m)
}
我们创建一个包含一些负值的 map 并将它们删除。匿名函数根据值定义了我们的删除条件。
基于键的删除
maps.DeleteFunc 可以使用键信息来决定删除。此示例删除键以“b”开头的条目。
package main
import (
"fmt"
"maps"
"strings"
)
func main() {
m := map[string]int{
"apple": 5,
"banana": 3,
"berry": 7,
"orange": 2,
}
maps.DeleteFunc(m, func(k string, v int) bool {
return strings.HasPrefix(k, "b")
})
fmt.Println("Map after deletion:", m)
}
测试函数会检查每个键的开头。所有键以“b”开头的条目都将从 map 中删除。
使用结构体值
我们可以将 maps.DeleteFunc 与包含结构体值的 map 一起使用。此示例删除不活跃的用户。
package main
import (
"fmt"
"maps"
)
type User struct {
Name string
Active bool
}
func main() {
users := map[int]User{
1: {"Alice", true},
2: {"Bob", false},
3: {"Charlie", true},
}
maps.DeleteFunc(users, func(k int, v User) bool {
return !v.Active
})
fmt.Println("Active users:", users)
}
该函数会检查每个用户的 Active 字段。不活跃的用户将从 map 中删除,而活跃的用户将保留。
合并键和值条件
复杂条件可以结合键和值的检查。此示例删除库存不足且 ID 特定的产品。
package main
import (
"fmt"
"maps"
)
func main() {
inventory := map[int]int{
101: 5,
102: 0,
103: 10,
201: 2,
202: 7,
}
maps.DeleteFunc(inventory, func(id int, stock int) bool {
return stock < 3 || id >= 200
})
fmt.Println("Filtered inventory:", inventory)
}
该条件结合了库存水平和产品 ID 检查。库存不足或 ID ≥ 200 的产品将被删除。
空映射行为
maps.DeleteFunc 可以优雅地处理空 map。此示例演示了其在空 map 上的行为。
package main
import (
"fmt"
"maps"
)
func main() {
m := map[string]int{}
maps.DeleteFunc(m, func(k string, v int) bool {
return true // Would delete all if any existed
})
fmt.Println("Empty map remains:", m)
}
由于没有要处理的元素,该函数什么也不做。操作后 map 仍然是空的。
性能注意事项
对于大型 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.DeleteFunc(largeMap, func(k, v int) bool {
return v%2 == 0
})
fmt.Println("Simple condition:", time.Since(start))
// Reset map
largeMap = make(map[int]int, 1_000_000)
for i := 0; i < 1_000_000; i++ {
largeMap[i] = i
}
// Complex condition
start = time.Now()
maps.DeleteFunc(largeMap, func(k, v int) bool {
return v%2 == 0 && k > 500_000 && v < 750_000
})
fmt.Println("Complex condition:", time.Since(start))
}
执行时间取决于条件的复杂性和删除的数量。maps.DeleteFunc 顺序处理每个元素。
实际示例:缓存清理
这个实际示例演示了如何通过删除过期的条目来使用 maps.DeleteFunc 进行缓存清理。
package main
import (
"fmt"
"maps"
"time"
)
type CacheEntry struct {
Value string
ExpireAt time.Time
}
func main() {
cache := map[string]CacheEntry{
"user:1": {"Alice", time.Now().Add(5 * time.Minute)},
"user:2": {"Bob", time.Now().Add(-1 * time.Hour)},
"user:3": {"Charlie", time.Now().Add(10 * time.Minute)},
}
maps.DeleteFunc(cache, func(k string, v CacheEntry) bool {
return time.Now().After(v.ExpireAt)
})
fmt.Println("Active cache entries:")
for k, v := range cache {
fmt.Printf("%s: %s\n", k, v.Value)
}
}
我们会将每个缓存条目的过期时间与当前时间进行比较。过期的条目将被删除,而有效的条目将保留在缓存中。
来源
本教程通过各种场景下条件性删除 map 元素的实际示例,介绍了 Go 中的 maps.DeleteFunc 函数。