我的印象是,只有当我们想要分配到双地图时,才会发生在nil地图错误中输入的分配,也就是说,当更高层上的地图试图被分配时不存在,例如:
var mm map[int]map[int]int
mm[1][2] = 3
但它也适用于简单的地图(虽然以结构为关键):
package main
import "fmt"
type COO struct {
x int
y int
}
var neighbours map[COO][]COO
func 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)
}
可能出现什么问题?
答案 0 :(得分:4)
您需要初始化邻居:var neighbours = make(map[COO][]COO)
请参阅:https://blog.golang.org/go-maps-in-action
中的第二部分每当您尝试将值插入尚未初始化的地图时,您都会感到恐慌。
答案 1 :(得分:3)
在Golang中,所有内容都初始化为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;
现在,对于更复杂的类型,例如chan
和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}}
最后,interface
和func
类型也初始化为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)