如何在Go中清除地图?


85

我在寻找类似c ++函数.clear() 的原始类型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"])
}

我的意思是,这仍然与.clear()c ++中的功能不同,后者将清除对象中的内容。



1
也有关于内置净化的讨论
Perreal

Answers:


108

您可能应该只创建一个新地图。没有真正的理由去尝试清除现有的代码,除非同一段映射被多个代码引用,并且一个代码段明确需要清除值,以便此更改对其他代码段可见。

是的,你可能应该说

mymap = make(map[keytype]valtype)

如果确实出于任何原因需要清除现有地图,这很简单:

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

1
因此,逐个删除元素是唯一的方法吗?
lavin 2012年

@lavin:是的。没有内置函数可以执行此操作,并且您不能具有针对任意地图执行此操作的库函数。但是反正只有三行。
莉莉·巴拉德

6
在遍历所有值的同时修改映射的内容真的可以吗?其他语言将无法与此一起正常工作。
约翰·杰弗里

5
@JohnJeffery:我在发布之前进行了测试。似乎可以工作。规范中的实际语言表示The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If map entries that have not yet been reached are deleted during iteration, the corresponding iteration values will not be produced. If map entries are inserted during iteration, the behavior is implementation-dependent, but the iteration values for each entry will be produced at most once. If the map is nil, the number of iterations is 0.这表示支持。
莉莉·巴拉德

18
从Go 1.11开始,此形式的地图清除操作由编译器优化。github.com/golang/go/blob/master/doc/go1.11.html
本杰明·B,

20

与C ++不同,Go是一种垃圾收集语言。您需要以不同的方式思考问题。

制作新地图时

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

原始地图最终将被垃圾收集;您无需手动清除它。但是请记住,地图(和切片)是引用类型;您使用创建它们make()。仅当没有引用时,才会对基础地图进行垃圾收集。因此,当你做

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

原始数组将不会被垃圾回收(直到b被垃圾回收或b引用其他东西)。


2
// 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{}

-5

如果您试图循环执行此操作,则可以利用初始化为您清除地图。例如:

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")
}

执行此操作时,它将清除先前的映射,并从一个空的映射开始。这由输出验证:

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

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

3
并不是清除地图,而是制作一个新地图并绑定到每个循环具有相同名称的局部变量。
Delaney
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.