Why does this code work
graph := make(map[int][]int, 0)
graph[0] = append(graph[0], 1)
But if you replace first line with graph := make([][]int, 0)
I get panic: runtime error: index out of range
? It's very weird.
The code panics due to slice length being 0
. If you want to append anything to the slice, you just have to provide its length as below.
graph := make([][]int, 1)
fmt.Println(len(graph))
graph[0] = append(graph[0], 1)
fmt.Println(graph)
To append data to a slice at first level, append to its first index and then append to second level just like below.
graph := make([][]int, 0)
fmt.Println(len(graph))
graph = append(graph, []int{1})
Check Playground example
Lets simplify your code, to make it more obvious what's happening (Playground link):
graph1 := make(map[int]int, 0)
graph2 := make([]int, 0)
x := graph1[0] // Success
y := graph2[0] // Panic
From this we see that the difference is due to map[int]
vs []int
-- the second array in your type is actually irrelevant.
Now to understand why this is happening, we need to understand how Go handles map and slice access. From Go Maps in Action we learn:
If the requested key doesn't exist, we get the value type's zero value.
In your original code, the zero value for a slice ([]int
), is nil
, and append()
treats nil
as the first argument as an empty slice.
But when we try to access the 0th element of an empty slice, we get a panic, because the slice is empty.
In summary, append
and the second slice of your type are both red herrings in your question. The panic happens when trying to access the non-existent element in the first dimension of your slice.
make(map[int][]int, 0)
creates a map
of []int
.
By design in Go you can get any element from a map. And if it doesn't exist you receive the "zero" value which here is an empty slice.
graph := make(map[int][]int)
graph[4] = append(graph[4], 1)
graph[7] = append([]int{}, 1, 2)
graph[11] = append([]int{1, 2, 3}, 4, 5)
printing it gives this slice:
fmt.Printf("%#v\n", graph)
map[int][]int{
4:[]int{1},
7:[]int{1, 2},
11:[]int{1, 2, 3, 4, 5},
}
Your second example create an empty slice of []int
slices. Slices work differently from maps, so indexing an element that doesn't exist will give you a panic.
When you do make in
graph := make(map[int][]int, 0)
, you are allocating memory to your map, not to array. So you might do this onlygraph := make(map[int][]int)
.Decomping you code:
See in playground.
The error that you are getting is caused for conceptual error. When you does
graph := make([][]int, 0)
, you are allocation memory to a slice of slice, not an array. See in https://blog.golang.org/go-slices-usage-and-internals.So you can does this (decomping solution):
See in playground