Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

initializing a struct containing a slice of structs in golang

Tags:

slice

struct

go

I have a struct that I want to initialize with a slice of structs in golang, but I'm trying to figure out if there is a more efficient version of appending every newly generated struct to the slice:

package main

import (
    "fmt"
    "math/rand"
)

type LuckyNumber struct {
    number int
}

type Person struct {
    lucky_numbers []LuckyNumber
}

func main() {
    count_of_lucky_nums := 10
    // START OF SECTION I WANT TO OPTIMIZE
    var tmp []LuckyNumber
    for i := 0; i < count_of_lucky_nums; i++ {
        tmp = append(tmp, LuckyNumber{rand.Intn(100)})
    }
    a := Person{tmp}
    // END OF SECTION I WANT TO OPTIMIZE
    fmt.Println(a)
}
like image 405
mgoldwasser Avatar asked Mar 03 '17 14:03

mgoldwasser


People also ask

How do I create a struct inside a struct in Golang?

A structure or struct in Golang is a user-defined type, which allows us to create a group of elements of different types into a single unit. Any real-world entity which has some set of properties or fields can be represented as a struct. Go language allows nested structure.

How do you initialize a struct value?

An initializer for a structure is a brace-enclosed comma-separated list of values, and for a union, a brace-enclosed single value. The initializer is preceded by an equal sign ( = ).

How do I create a new struct object in Golang?

2 ways to create and initialize a new structThe new keyword can be used to create a new struct. It returns a pointer to the newly created struct. You can also create and initialize a struct with a struct literal. An element list that contains keys does not need to have an element for each struct field.


2 Answers

You can use make() to allocate the slice in "full-size", and then use a for range to iterate over it and fill the numbers:

tmp := make([]LuckyNumber, 10)
for i := range tmp {
    tmp[i].number = rand.Intn(100)
}
a := Person{tmp}
fmt.Println(a)

Try it on the Go Playground.

Note that inside the for I did not create new "instances" of the LuckyNumber struct, because the slice already contains them; because the slice is not a slice of pointers. So inside the for loop all we need to do is just use the struct value designated by the index expression tmp[i].

like image 138
icza Avatar answered Oct 11 '22 20:10

icza


You can use make() the way icza proposes, you can also use it this way:

tmp := make([]LuckyNumber, 0, countOfLuckyNums)
for i := 0; i < countOfLuckyNums; i++ {
    tmp = append(tmp, LuckyNumber{rand.Intn(100)})
}
a := Person{tmp}
fmt.Println(a)

This way, you don't have to allocate memory for tmp several times: you just do it once, when calling make. But, contrary to the version where you would call make([]LuckyNumber, countOfLuckyNums), here, tmp only contains initialized values, not uninitialized, zeroed values. Depending on your code, it might make a difference or not.

like image 20
Fabien Avatar answered Oct 11 '22 20:10

Fabien