Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preallocate and fill a slice of pointers in a go-idiomatic way?

Tags:

slice

go

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?

like image 711
Dante Avatar asked Jun 03 '13 21:06

Dante


People also ask

How do you input slice in go?

Using make() function: You can also create a slice using the make() function which is provided by the go library. This function takes three parameters, i.e, type, length, and capacity. Here, capacity value is optional.

Is slice a pointer in go?

Slices are pointers to arrays, with the length of the segment, and its capacity. They behave as pointers, and assigning their value to another slice, will assign the memory address.

How do you make a slice in Golang?

Golang make() is a built-in slice function used to create a slice. The make() function takes three arguments: type, length, and capacity, and returns the slice. To create dynamically sized arrays, use the make() function. The make() function allocates a zeroed array and returns a slice that refers to that array.

What are some of the advantages of using structs over maps and slices?

A struct is just often more useful in Go, since the fields and their types are statically known, as well as being more efficient, since fields are stored directly and at known offsets which don't need to be computed on each access.


1 Answers

For your first example, I would do:

mySlice := make([]*UselessStruct, 5) for i := range mySlice {      mySlice[i] = new(UselessStruct) } 

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.

mySlice := make([]*UselessStruct, 0, 5) for i := 0; i != 5; i++ {     mySlice = append(mySlice, &UselessStruct{}) } // mySlice is [0xc010035160 0xc010035170 0xc010035180 0xc010035190 0xc0100351a0] 

Both of my examples will work as you expect but I recommend the first one for purely style reasons.

like image 153
Stephen Weinberg Avatar answered Sep 21 '22 13:09

Stephen Weinberg