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

恐慌:在单个简单地图上分配零地图中的条目

恐慌:在单个简单地图上分配零地图中的条目

Go
红糖糍粑 2022-01-17 10:44:49
我的印象是,只有当我们想要分配给双映射时,才会发生在 nil 映射错误中的条目分配,也就是说,当试图分配更深级别的映射而更高级别的映射没有时存在,例如:var mm map[int]map[int]intmm[1][2] = 3但它也发生在一个简单的地图上(尽管以 struct 作为键):package mainimport "fmt"type COO struct {    x int    y int}var neighbours map[COO][]COOfunc main() {    for i := 0; i < 30; i++ {        for j := 0; j < 20; j++ {            var buds []COO            if i < 29 {                buds = append(buds, COO{x: i + 1, y: j})            }            if i > 0 {                buds = append(buds, COO{x: i - 1, y: j})            }            if j < 19 {                buds = append(buds, COO{x: i, y: j + 1})            }            if j > 0 {                buds = append(buds, COO{x: i, y: j - 1})            }            neighbours[COO{x: i, y: j}] = buds // <--- yields error        }    }    fmt.Println(neighbours)}有什么问题?
查看完整描述

2 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

您需要初始化邻居: var neighbours = make(map[COO][]COO)

见第二部分:https ://blog.golang.org/go-maps-in-action

每当您尝试将值插入尚未初始化的映射时,您都会感到恐慌。


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

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

在 Golang 中,一切都被初始化为 a zero value,它是未初始化变量的默认值。


因此,正如已经设想的那样,地图的零值为零。尝试使用未初始化的地图时,它会出现恐慌。(一种空指针异常)


有时它可能很有用,因为如果您知道某物的零值,则不必显式初始化它:


var str string

str += "42"

fmt.Println(str)

// 42 ; A string zero value is ""


var i int

i++

fmt.Println(i)

// 1 ; An int zero value is 0


var b bool

b = !b

fmt.Println(b)

// true ; A bool zero value is false

如果你有 Java 背景,那也是一样的:原始类型有一个默认值,对象被初始化为 null;


现在,对于像chanand这样的更复杂的类型map,零值是nil,这就是你必须使用make实例化它们的原因。指针也有零值。数组和切片的情况有点棘手:


var a [2]int

fmt.Println(a)

// [0 0]


var b []int

fmt.Println(b)

// [] ; initialized to an empty slice

编译器知道数组的长度(不能更改)及其类型,因此它已经可以实例化正确数量的内存。所有值都被初始化为零值(与 C 不同,您可以在数组中包含任何内容)。对于切片,初始化为空切片[],可以append正常使用。


现在,对于结构,它与数组相同。Go 创建一个结构体,其所有字段都初始化为零值。它进行了深度初始化,示例如下:


type Point struct {

    x int

    y int

}


type Line struct {

    a Point

    b Point

}


func main() {

    var line Line

    // the %#v format prints Golang's deep representation of a value

    fmt.Printf("%#v\n", line)

}

// main.Line{a:main.Point{x:0, y:0}, b:main.Point{x:0, y:0}}

最后,interfaceandfunc类型也被初始化为 nil。


这就是它的全部。使用复杂类型时,您只需要记住初始化它们。唯一的例外是数组,因为你不能这样做make([2]int)。


在您的情况下,您有切片映射,因此您至少需要两个步骤才能在其中放入一些内容:初始化嵌套切片,并初始化第一个映射:


var buds []COO

neighbours := make(map[COO][]COO)

neighbours[COO{}] = buds


// alternative (shorter)

neighbours := make(map[COO][]COO)


// You have to use equal here because the type of neighbours[0] is known

neighbours[COO{}] = make([]COO, 0)


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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信