Go语言 如何在围棋中清空Map?

2q5ifsrm  于 2022-12-07  发布在  Go
关注(0)|答案(6)|浏览(154)

我正在寻找一些类似于c++函数.clear()的东西,用于原始类型map
或者我应该创建一个新的Map?
更新:感谢您的回答。通过查看这些回答,我刚刚意识到有时创建新Map可能会导致一些我们不希望出现的不一致。请考虑以下示例:

var a map[string]string
var b map[string]string

func main() {
    a = make(map[string]string)
    b=a
    a["hello"]="world"
    a = nil
    fmt.Println(b["hello"])
}

我的意思是,这仍然不同于c++中的.clear()函数,它将清除对象中的内容。

zxlwwiss

zxlwwiss1#

你可能应该创建一个新的Map,没有必要去清除一个已经存在的Map,除非同一个Map被多段代码引用,并且其中一段代码需要明确地清除值,这样其他代码就可以看到这个变化。
所以你应该直接说

mymap = make(map[keytype]valtype)

如果出于某种原因确实需要清除现有Map,这很简单:

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

gijlo24d2#

与C++不同,Go语言是一种垃圾收集语言,你需要换一种思路。
创建新Map时

a := map[string]string{"hello": "world"}
a = make(map[string]string)

原始Map最终将被垃圾收集;你不需要手动清除它,但是记住Map(和切片)是引用类型;您使用make()创建它们。只有当没有对底层Map的引用时,才会对其进行垃圾回收。因此,当您

a := map[string]string{"hello": "world"}
b := a
a = make(map[string]string)

原始数组将不被垃圾收集(直到b被垃圾收集或b引用其它内容)。

lymgl2op

lymgl2op3#

// Method - I , say book is name of map
for k := range book {
    delete(book, k)
}

// Method - II
book = make(map[string]int)

// Method - III
book = map[string]int{}
mrfwxfqh

mrfwxfqh4#

达到1.18及以上

您可以使用maps.Clear。该函数属于golang.org/x/exp/maps包(实验性的,不在兼容性保证范围内)
Clear会移除m中的所有项目,让它保持空白。
示例用法:

func main() {
    testMap := map[string]int{"gopher": 1, "badger": 2}
    maps.Clear(testMap)
    fmt.Println(testMap)
    
    testMap["zebra"] = 2000
    fmt.Println(testMap)
}

Playground:https://go.dev/play/p/qIdnGrd0CYs?v=gotip
如果你不想依赖于实验性的软件包,你可以复制粘贴源代码,这实际上非常简单:

func Clear[M ~map[K]V, K comparable, V any](m M) {
    for k := range m {
        delete(m, k)
    }
}

重要说明:就像内置的deletemaps.Clear的实现使用它)一样,这个不会从Map中删除非自反键。原因是对于非自反键,根据定义,x == x是false。非自反键是NaN浮点数,以及支持比较运算符但在某处包含NaN浮点数的所有其他类型。

请参阅以下代码以了解这需要什么:

func main() {
    m := map[float64]string{}
    m[1.0] = "foo"

    k := math.NaN()
    fmt.Println(k == k) // false
    m[k] = "bar"

    maps.Clear(m)
    fmt.Printf("len: %d, content: %v\n", len(m), m) 
    // len: 1, content: map[NaN:bar]

    a := map[[2]float64]string{}
    a[[2]float64{1.0, 2.0}] = "foo"

    h := [2]float64{1.0, math.NaN()}
    fmt.Println(h == h) // false
    a[h] = "bar"

    maps.Clear(a)
    fmt.Printf("len: %d, content: %v\n", len(a), a) 
    // len: 1, content: map[[1 NaN]:bar]
}

Playground:https://go.dev/play/p/LWfiD3iPA8Q
目前正在讨论clear内置函数(2022年秋季),如果添加到下一个Go语言版本中,也将删除非自反键。

s3fp2yjn

s3fp2yjn5#

Go语言中清除Map的方法

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

**仅当m不包含包含NaN**的键值时才有效。

delete(m, k)不适用于任何非自反键(如math.NaN()),但也适用于结构体或其他类似的类型,其中包含任何NaN浮点数。给定struct{ val float64 }NaN瓦尔也是非自反的(引用自blackgreen注解)
为了解决这个问题并支持在Go语言中清除Map,新版本中可能会提供一个buildin clear(x)函数,更多细节请参考add clear(x) builtin, to clear map, zero content of slice, ptr-to-array

nszi6y05

nszi6y056#

如果你想在循环中完成这个操作,你可以利用初始化来清除Map。例如:

for i:=0; i<2; i++ {
    animalNames := make(map[string]string)
    switch i {
        case 0:
            animalNames["cat"] = "Patches"
        case 1:
            animalNames["dog"] = "Spot";
    }

    fmt.Println("For map instance", i)
    for key, value := range animalNames {
        fmt.Println(key, value)
    }
    fmt.Println("-----------\n")
}

当你执行这个命令时,它会清除之前的Map,并从一个空Map开始。

$ go run maptests.go 
For map instance 0
cat Patches
-----------

For map instance 1
dog Spot
-----------

相关问题