http://play.golang.org/p/j-Y0mQzTdP
package main
import "fmt"
type UselessStruct struct {
a int
b int
}
func main() {
mySlice := make([]*UselessStruct, 5)
for i := 0; i != 5; i++ {
mySlice = append(mySlice, &UselessStruct{})
}
fmt.Println(mySlice)
}
Outputs: [<nil> <nil> <nil> <nil> <nil> 0xc010035160 0xc010035170 0xc010035180 0xc010035190 0xc0100351a0]
What i would like to do, is preallocate memory for 5 UselessStructs, stored as pointers. If i declare a slice of struct values eq:
mySlice := make([]UselessStruct, 5)
then this creates 5 empty structs – appending doesn't replace the empty structs, but rather keeps on adding to the slice, so the end result with this code:
http://play.golang.org/p/zBYqGVO85h
package main
import "fmt"
type UselessStruct struct {
a int
b int
}
func main() {
mySlice := make([]UselessStruct, 5)
for i := 0; i != 5; i++ {
mySlice = append(mySlice, UselessStruct{})
}
fmt.Println(mySlice)
}
is: [{0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0}]
What is the the go-idiomatic way to preallocate and fill slices?
Best Answer
For your first example, I would do:
The issue you are facing in both examples is you are appending to a slice that is already the correct length. If you set
mySlice := make([]*UselessStruct, 5)
, you are asking for a slice of nil pointers of length 5. If you append one pointer, it now has length 6.Instead, you want to use
mySlice := make([]*UselessStruct, 0, 5)
. This creates a slice of length 0 but capacity 5. Each time you append it will add one to the length but it won't reallocate until you exceed the slice's capacity.Both of my examples will work as you expect but I recommend the first one for purely style reasons.