地图类型是引用类型。 var m map [string] int不指向初始化的地图。这是什么意思?

时间:2016-06-01 12:13:53

标签: go

我在golang博客上看过:https://blog.golang.org/go-maps-in-action

m = make(map[string]int)
     

地图类型是引用类型,如指针或切片,等等   m以上的值为零;它没有指向初始化的地图。没有   在阅读时,map的行为类似于空地图,但尝试写入   零映射会导致运行时恐慌;不要这样做。初始化一个   map,使用内置的make函数:

var m map[string]int
     

make函数分配并初始化哈希映射数据结构   并返回指向它的地图值。

我很难理解其中的一些部分:

  • m = make(map[string]int)做什么?
  • 为什么我需要写i = make(int)而不是 XzibitVideo programVideo = new XzibitVideo(); programVideo.launch(XzibitVideo.class); this.dispose();

3 个答案:

答案 0 :(得分:3)

  

var m map [string] int做什么?

它告诉编译器mmap[string]int类型的变量,并指定"零值"类型map [string] int到m的类型(这就是为什么m为nil为nil为任何地图的零值)。

  

为什么我需要写m = make(map [string] int)但不是i = make(int)

你不需要。您可以创建一个初始化的地图,如下所示:

m = map[string]int{}

完全相同。

地图和整数之间的区别是:零地图非常好。例如。 nil映射的len()有效,并且为0.对于nil映射,唯一不能做的就是存储键值对。如果你想这样做,你必须准备/初始化地图。 Go中的这个准备/初始化是通过内置make(或如上所示的文字地图)完成的。整数不需要这个初始化过程。由于没有零值,因此初始化将是总噪声。

请注意,您没有初始化变量 m:变量m是一个字符串到int的映射,已初始化或未初始化。像i一样是int的变量。现在,int可以直接使用,而map需要多一步,因为语言可以这样工作。

答案 1 :(得分:2)

  

var m map [string] int做什么?

你可以把它看作是带有nil值的指针,它不指向任何东西,但能够指向具体的价值。

  

为什么我需要写m = make(map [string] int)但不是i = make(int)

https://golang.org/doc/effective_go.html#allocation_make

回到分配。内置函数make(T,args)用于与new(T)不同的用途。它仅创建切片,贴图和通道,并返回类型为T(不是* T)的初始化(未归零)值。区别的原因是这三种类型在封面下表示对在使用前必须初始化的数据结构的引用。例如,切片是一个三项描述符,包含指向数据的指针(在数组内),长度和容量,并且在初始化这些项之前,切片为零。对于切片,贴图和通道,请初始化内部数据结构并准备要使用的值。例如,

make([]int, 10, 100)

分配一个100个整数的数组,然后创建一个长度为10且容量为100的切片结构,指向数组的前10个元素。 (制作切片时,可以省略容量;有关详细信息,请参阅切片部分。)相反,new([] int)返回指向新分配的零化切片结构的指针,即指向a的指针零片值。

这些例子说明了new和make之间的区别。

var p *[]int = new([]int)       // allocates slice structure; *p == nil; rarely useful
var v  []int = make([]int, 100) // the slice v now refers to a new array of 100 ints

// Unnecessarily complex:
var p *[]int = new([]int)
*p = make([]int, 100, 100)

// Idiomatic:
v := make([]int, 100)

请记住,make仅适用于地图,切片和通道,并且不会返回指针。获取显式指针,使用new分配或明确地获取变量的地址。

答案 2 :(得分:2)

所有字的长度都相同 32位(4字节) 64位(8字节), 取决于处理器和操作系统。它们由其内存地址标识(表示为十六进制数)。

原始类型的所有变量 ,例如 int float bool 字符串 ...是value types,它们直接指向内存中包含的值。数组和结构等复合类型也是值类型。使用=将值类型的值分配给另一个变量j = i时,会在内存中创建原始值i的副本。

通常需要多个单词的更复杂数据被视为 引用类型 。引用类型变量r1包含存储r1值的内存位置的地址(数字)(或至少是它的第一个字):

enter image description here

对于分配r2 = r1时的参考类型,仅复制参考(地址)而不是值!!。如果修改了r1的值,则将反映该值的所有引用(如r1和r2)。

在Go指针中有引用类型,以及切片,贴图和通道。引用的变量存储在堆中,这是垃圾回收。

根据上述陈述,该文章明确说明原因:

  

要初始化地图,请使用内置的make函数。

make函数分配并初始化哈希映射数据结构并返回指向它的映射值。这意味着您可以写入,与

进行比较
var m map[string]int

是可读的,产生nil映射,但尝试写入nil映射将导致运行时混乱。这就是使用make初始化地图非常重要的原因。

m = make(map[string]int)