ZetCode

Golang maps.Delete

最后修改于 2025 年 4 月 20 日

本教程将介绍如何在 Go 中使用 maps.Delete 函数。我们将通过删除键值对的实际示例来讲解 Map 操作。

maps.Delete 函数从 Map 中删除一个键值对。它是 Go 1.21 中引入的实验性 maps 包的一部分。

此函数可用于安全地从 Map 中删除条目,而无需先检查键是否存在。它能优雅地处理不存在的键。

基本的 maps.Delete 示例

maps.Delete 最简单的用法是删除 Map 中的一个键。我们创建一个 Map 并删除其中一个条目。

basic_delete.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    fruits := map[string]int{
        "apple":  5,
        "banana": 3,
        "orange": 2,
    }
    
    maps.Delete(fruits, "banana")
    fmt.Println("Map after deletion:", fruits)
}

我们创建一个水果库存 Map 并删除 "banana" 条目。该函数会就地修改 Map,不返回任何内容。

删除不存在的键

maps.Delete 安全地处理尝试删除不存在键的情况。此示例展示了这种行为。

nonexistent_key.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    capitals := map[string]string{
        "France":  "Paris",
        "Germany": "Berlin",
    }
    
    maps.Delete(capitals, "Italy")
    fmt.Println("Map remains unchanged:", capitals)
}

尝试删除 "Italy"(不存在)不会导致错误。Map 保持不变,显示了该函数是安全的。

删除多个键

我们可以在循环中使用 maps.Delete 来删除多个键。此示例一次删除多个条目。

multiple_deletes.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    scores := map[string]int{
        "Alice":   85,
        "Bob":     72,
        "Charlie": 90,
        "Dave":    68,
    }
    
    toDelete := []string{"Bob", "Dave", "Eve"}
    
    for _, name := range toDelete {
        maps.Delete(scores, name)
    }
    
    fmt.Println("Scores after deletions:", scores)
}

我们遍历要删除的名称切片。该函数安全地处理 Map 中不存在的 "Eve"。

与 maps.Clone 结合使用

我们可以将 maps.Deletemaps.Clone 结合使用来修改 Map 的副本。此示例演示了非破坏性删除。

clone_and_delete.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    original := map[int]string{
        1: "one",
        2: "two",
        3: "three",
    }
    
    copy := maps.Clone(original)
    maps.Delete(copy, 2)
    
    fmt.Println("Original:", original)
    fmt.Println("Modified copy:", copy)
}

我们在删除前克隆原始 Map。这可以保留原始数据,同时允许我们使用修改后的版本。

性能注意事项

在大多数情况下,maps.Delete 具有恒定时间性能。此示例对删除操作进行基准测试。

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 * 2
    }
    
    start := time.Now()
    maps.Delete(largeMap, 500_000)
    fmt.Println("Delete middle element:", time.Since(start))
    
    start = time.Now()
    maps.Delete(largeMap, 999_999)
    fmt.Println("Delete last element:", time.Since(start))
    
    start = time.Now()
    maps.Delete(largeMap, -1) // Doesn't exist
    fmt.Println("Delete non-existent:", time.Since(start))
}

删除时间通常为 O(1),与 Map 大小或键位置无关。该示例显示了不同场景下的一致性能。

实际示例:缓存管理

这个实际示例展示了在缓存系统中使用 maps.Delete。我们通过删除过时条目来实现基本的缓存过期。

cache_management.go
package main

import (
    "fmt"
    "maps"
    "time"
)

type CacheEntry struct {
    Value    string
    ExpireAt time.Time
}

func main() {
    cache := make(map[string]CacheEntry)
    
    // Add some entries
    cache["user1"] = CacheEntry{"Alice", time.Now().Add(5 * time.Minute)}
    cache["user2"] = CacheEntry{"Bob", time.Now().Add(-1 * time.Minute)} // Expired
    
    // Cleanup expired entries
    for key, entry := range cache {
        if time.Now().After(entry.ExpireAt) {
            maps.Delete(cache, key)
        }
    }
    
    fmt.Println("Cache after cleanup:", cache)
}

我们遍历缓存并删除过期的条目。这展示了 Map 删除在资源管理中的实际用例。

与 delete 内置函数对比

此示例将 maps.Delete 与 Go 的内置 delete 函数进行了比较。两者都实现了相似的结果。

comparison.go
package main

import (
    "fmt"
    "maps"
)

func main() {
    map1 := map[string]int{"a": 1, "b": 2, "c": 3}
    map2 := maps.Clone(map1)
    
    // Using maps.Delete
    maps.Delete(map1, "b")
    
    // Using built-in delete
    delete(map2, "b")
    
    fmt.Println("maps.Delete result:", map1)
    fmt.Println("built-in delete result:", map2)
}

两种方法都产生相同的结果。maps.Delete 是实验性 maps 包的一部分,而 delete 是语言内置的。

来源

Go 实验性 maps 包文档

本教程通过在各种场景下删除 Map 中的键值对的实际示例,讲解了 Go 中的 maps.Delete 函数。

作者

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

列出所有 Go 教程