【问题标题】:Delete key in map删除地图中的键
【发布时间】:2010-12-16 16:47:59
【问题描述】:

我有一张地图:

var sessions =  map[string] chan int{}

如何删除sessions[key]?我试过了:

sessions[key] = nil,false;

那没用。

更新(2011 年 11 月):

删除映射条目的特殊语法在Go version 1中被移除:

Go 1 将删除特殊的映射分配并引入一个新的内置函数deletedelete(m, x) 将删除表达式m[x] 检索到的映射条目。 ...

【问题讨论】:

    标签: dictionary go


    【解决方案1】:

    来自Effective Go

    要删除地图条目,请使用 delete 内置函数,其参数是地图和要删除的键。即使地图上已经没有密钥,这样做也是安全的。

    delete(timeZone, "PDT")  // Now on Standard Time
    

    【讨论】:

    • sessions.go:6: cannot use 0 (type int) as type chan int
    • @Kinopiko:我认为 Jurily 并不是要让 OP 使用该代码 sn-p。他只是从文档中复制了一个示例。
    • 看起来这个已经被删除了,得到assignment count mismatch: 1 = 2 (use delete)
    【解决方案2】:

    复制自 Go 1 release notes

    在旧语言中,要从m 表示的映射中删除键为k 的条目,请编写语句,

    m[k] = value, false
    

    这种语法是一种特殊的特殊情况,是唯一的二对一赋值。它需要传递一个被评估但被丢弃的值(通常被忽略),加上一个几乎总是为假的布尔值。它完成了这项工作,但很奇怪并且是一个争论点。

    在 Go 1 中,该语法已经消失;取而代之的是一个新的内置函数delete。来电

    delete(m, k)
    

    将删除由表达式m[k] 检索到的映射条目。没有返回值。删除不存在的条目是无操作的。

    更新: 运行go fix 会将m[k] = value, false 形式的表达式转换为delete(m, k),当很明显可以从程序中安全地丢弃忽略的值并且false 指的是预定义的布尔常量。修复工具将标记语法的其他用途以供程序员检查。

    【讨论】:

    • 无操作是什么意思?
    • @humble 没有操作发生,没有错误,执行只是继续。我相信它来自x86指令NOP,它只是让执行继续到下一条指令
    • @Alex Trivia item -- NOP 指令至少可以追溯到 1950 年代早期,IBM 701 的 NoOp 指令。我不确定在此之前是否有先例。
    • 为什么删除一个不存在的条目是无操作的呢?我会假设它至少会进行键查找,因为编译器在一般情况下可能不知道键是否是映射的一部分。
    【解决方案3】:
    delete(sessions, "anykey")
    

    这些天,什么都不会崩溃。

    【讨论】:

    【解决方案4】:

    使用make (chan int) 代替nil。第一个值必须与您的地图具有相同的类型。

    package main
    
    import "fmt"
    
    func main() {
    
        var sessions = map[string] chan int{}
        sessions["somekey"] = make(chan int)
    
        fmt.Printf ("%d\n", len(sessions)) // 1
    
        // Remove somekey's value from sessions
        delete(sessions, "somekey")
    
        fmt.Printf ("%d\n", len(sessions)) // 0
    }
    

    更新:更正了我的答案。

    【讨论】:

    • sessions.go:6: cannot use 0 (type int) as type chan int
    • 哎呀,忘了我也删除了:P
    • package main func main () {var sessions = map[string] chan int{};sessions["moo"] = make (chan int);}
    • 以上在我的 Go 版本上编译并运行。
    【解决方案5】:

    很奇怪,

    package main
    
    func main () {
        var sessions = map[string] chan int{};
        delete(sessions, "moo");
    }
    

    似乎有效。不过,这似乎对资源的使用很糟糕!

    另一种方法是检查是否存在并使用值本身:

    package main
    
    func main () {
        var sessions = map[string] chan int{};
        sessions["moo"] = make (chan int);
        _, ok := sessions["moo"];
        if ok {
            delete(sessions, "moo");
        }
    }
    

    【讨论】:

    • 查找价值并重复使用它必须更便宜:sessions["moo"] = sessions["moo"], false;(或者说错了吗?)
    • 除非密钥存在,否则会崩溃。我根据您的想法添加了另一个解决方案。
    • 在测距地图本身时使用它是否安全?
    • @JorgeRamirez 我不这么认为。如果您想这样做,请找到一种方法来迭代键的一部分而不是映射对象本身
    • 为什么第二种方案更好地利用资源?在第二个解决方案中,您执行两个键查找,而在第一个解决方案中,您执行一个键查找。
    猜你喜欢
    • 2021-06-07
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多