Why can't I initialize a map with new() in Go?

主宰稳场 提交于 2021-02-17 06:01:33

问题


package main

import "fmt"

func main() {
    p := new(map[string]int)
    m := make(map[string]int)
    m["in m"] = 2
    (*p)["in p"] = 1
    fmt.Println(m)
    fmt.Println(*p)
}

The above code gives an error panic: assignment to entry in nil map. If I print *p before inserting pairs into it, the output is correct. It seems I just can't modify *p?


回答1:


Both new and make are used to allocate memory in a program, but they work differently. new(T, args) zeros memory and returns the memory address (a value of type *T) but does not initialize that memory. make(T, args) on the other hand initializes a value of type T. A map need to be initialized because, while a map can be empty, there is still the structure of the map itself, which is non-zero and therefore needs to be initialized before use.

From Effective Go:

The built-in function make(T, args) serves a purpose different from new(T). It creates slices, maps, and channels only, and it returns an initialized (not zeroed) value of type T (not *T). The reason for the distinction is that these three types represent, under the covers, references to data structures that must be initialized before use. A slice, for example, is a three-item descriptor containing a pointer to the data (inside an array), the length, and the capacity, and until those items are initialized, the slice is nil. For slices, maps, and channels, make initializes the internal data structure and prepares the value for use.




回答2:


This is not directly an issue with new keyword. You would get the same behavior, if you did not initialize your map, when declaring it with var keyword, for example:

var a map[string]int
a["z"] = 10

The way to fix this is to initialize the map:

var a map[string]int
a = map[string]int{}
a["z"] = 10

And it works the same way, with new keyword:

p := new(map[string]int)
*p = map[string]int{}
(*p)["in p"] = 1 

The reason make(map[string]int) does what you expect is that the map is declared and initialized.

Go Playground



来源:https://stackoverflow.com/questions/53799199/why-cant-i-initialize-a-map-with-new-in-go

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!