为了账号安全,请及时绑定邮箱和手机立即绑定

Go中的地图初始化

Go中的地图初始化

Go
catspeake 2023-06-01 14:21:21
据我了解,Go 中的类型slice和map在很多方面都很相似。他们都是reference(或container)类型。在抽象数据类型方面,它们分别表示数组和关联数组。然而,他们的行为却截然不同。var s []int var m map[int]int虽然我们可以立即使用声明的切片(附加新项或重新切片),但我们不能对新声明的映射做任何事情。我们必须显make式调用函数并初始化地图。因此,如果某个结构包含一个映射,我们必须为该结构编写一个构造函数。所以,问题是为什么不能在声明映射时添加一些语法糖并同时分配和初始化内存。我确实用谷歌搜索了这个问题,学到了一个新词“avtovivification”,但仍然看不出原因。我不是在谈论结构文字。是的,您可以通过提供诸如m := map[int]int{1: 1}. 但是,如果您有一些结构:package mainimport (    "fmt")type SomeStruct struct {    someField map[int]int    someField2 []int}func main() {    s := SomeStruct{}    s.someField2 = append(s.someField2, -1) // OK    s.someField[0] = -1 // panic: assignment to entry in nil map    fmt.Println(s)}不可能立即使用结构(所有字段都使用默认值)。必须创建一个构造函数,该函数SomeStruct必须显式初始化映射。
查看完整描述

2 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

虽然我们可以立即使用声明的切片(附加新项或重新切片),但我们不能对新声明的映射做任何事情。我们必须显make式调用函数并初始化地图。因此,如果某个结构包含一个映射,我们必须为该结构编写一个构造函数。

这不是真的。切片和映射的默认值(或更准确地说是零值nil)是. nil您可以对地图执行与对切片执行的“相同”操作nil。你可以检查nil地图的长度,你可以索引nil地图(结果将是地图值类型的零值),例如以下所有工作:

var m map[int]int


fmt.Println(m == nil) // Prints true

fmt.Println(len(m))   // Prints 0

fmt.Println(m[2])     // Prints 0

在Go Playground上尝试一下。

您对零值切片的更多“感觉”是您可以为其添加值。这是事实,但在幕后,将使用make()您必须为地图调用的确切内置函数来分配一个新切片,以便向其添加条目,并且您必须(重新)分配返回的切片。因此,零值切片与零值映射“无法使用”。append()只负责必要的(重新)分配和复制。我们可以有一个“等效”addEntry()函数,您可以将映射值和键值对传递给它,如果传递的映射是nil,它可以分配一个新的映射值并返回它。如果不调用append(),就不能向nil切片添加值,就像不能向nil映射添加条目一样。

nil切片和映射的零值(而不是初始化的切片或映射)的主要原因是性能和效率。通常,映射或切片值(变量或结构字段)永远不会被使用,或者不会立即使用,因此如果它们在声明时分配,那将是内存(和一些 CPU)的浪费资源,更不用说它为垃圾收集器提供了更多工作。此外,如果零值是一个初始化值,它通常是不够的(例如,一个 0 大小的切片不能容纳任何元素),并且当您向它添加新元素时它通常会被丢弃(因此初始分配将是完全浪费)。

是的,有些情况下您确实想立即使用切片和映射,在这种情况下您可以调用make()自己,或使用复合文字。您还可以使用特殊形式make()为地图提供(初始)容量,避免未来地图内部结构的重组(这通常需要不可忽略的计算)。自动非nil默认值无法猜测您需要的容量。


查看完整回答
反对 回复 2023-06-01
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

你可以!您正在寻找的是:


package main


import "fmt"


func main() {

    v := map[int]int{}


    v[1] = 1

    v[2] = 2


    fmt.Println(v)

}

:=是声明和分配,其中 asvar只是声明。


查看完整回答
反对 回复 2023-06-01
  • 2 回答
  • 0 关注
  • 168 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号