web-dev-qa-db-ja.com

golangで構造体のスライスを含む構造体を初期化する

Golangの構造体のスライスで初期化する構造体がありますが、新しく生成されたすべての構造体をスライスに追加するより効率的なバージョンがあるかどうかを把握しようとしています:

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)
}
8
mgoldwasser

make() を使用してスライスを「フルサイズ」に割り当て、次に for range を使用してスライスを反復して塗りつぶすことができます。数字:

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

Go Playground で試してください。

for内には、LuckyNumber構造体の新しい「インスタンス」を作成しなかったことに注意してください。スライスにはすでにそれらが含まれているためです。スライスはポインターのスライスではないためです。したがって、forループ内で行う必要があるのは、 インデックス式tmp[i]で指定された構造体値を使用することだけです。

11
icza

Iczaが提案する方法でmake()を使用できますが、この方法でも使用できます。

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

この方法では、tmpにメモリを数回割り当てる必要はありません。makeを呼び出すときに一度だけ割り当てます。ただし、make([]LuckyNumber, countOfLuckyNums)を呼び出すバージョンとは異なり、ここでtmpには初期化された値のみが含まれ、初期化されていないゼロ値は含まれません。コードに応じて、違いが生じる場合とそうでない場合があります。

3
Fabien