美文网首页
为什么Golang需要一个内置clear函数?

为什么Golang需要一个内置clear函数?

作者: 夕午wuw | 来源:发表于2022-11-20 15:30 被阅读0次

    最近我看到Golang社区有一个非常有意思的提议,想要给Golang增加一个内置的clear()函数,来清除map、无内容的slice、指向array的指针等:proposal: spec: add clear(x) builtin, to clear map, zero content of slice, ptr-to-array #56351。在golang中清除一个map的所有元素,目前只有通过for循环+delete的方式,这确实不太优雅。

    for k := range m {
       delete(m, k)
    }
    

    对于map来说,for循环+delete的方式还有一个缺点,即map中的 空bucket 不会被删除,仍然会占用部分空间。具体原因可以自行搜索,本文不做详细介绍。

    但其实,delete函数还存在一个小问题,而这个小问题让 delete函数的正确性 受到影响。我们看看下面这段代码:

    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
        m := make(map[float64]string)
        m[math.NaN()] = "Yes"
        for k := range m {
            delete(m, k)
        }
        fmt.Printf("Map has length %d, contents: %#v\n", len(m), m)
        // 输出:Map has length 1, contents: map[float64]string{NaN:"Yes"}
    }
    

    感兴趣的读者可以自己跑一次试试。很明显,这里的代码运行结果与我们的预期不一致!如果map中存在以浮点数NaN为key的元素,你无法删除它。 造成这一问题的原因在于,Golang对浮点数的比较操作遵从IEEE754标准 Floating-point values are comparable and ordered, as defined by the IEEE-754 standard. 在这一标准下,NaN与任何浮点数都不相等,并且两个NaN之间也不相等。

    而delete(m, k)函数需要通过对比值,删除与k相等的元素,如果m中没有与k相等的元素,delete函数什么也不做。所以,delete函数无法删除map中将NaN作为key的元素(即使你可以用range来迭代出它)

    我在读到这一提案之前,并不知道NaN带来的问题,对此我也十分惊讶。增加一个内置的clear函数,固然能够提升代码效率,但更重要的是修正一个遗留的代码正确性问题,希望能在go 1.21版本中看到这一改进吧!

    相关文章

      网友评论

          本文标题:为什么Golang需要一个内置clear函数?

          本文链接:https://www.haomeiwen.com/subject/xyrwxdtx.html