在golang中初始化一个包含结构片断的结构体
我有一个结构体,我想用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)
}
您可以使用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
循环中,我们只需使用由index expressiontmp[i]
指定的结构值。
您可以使用make()
icza提出了解决方案,你也可以使用这种方式:
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
只包含初始值,而不是未初始化的归零值。根据你的代码,它可能会有所作为。
我认为你的答案也可以,但为什么其他答案会不止一次地为tmp分配内存? – mgoldwasser
切片'tmp'最初是空的。当您第一次追加到它时,运行时会分配一个小的基础数组并将值放入其中。当您继续追加切片时,一旦达到分配的基础数组的容量,运行时就必须分配一个新的更大的数组,并将所有内容从第一个切换到新切入点。它必须多次执行此操作以适应重复的附加内容(本例中为4个分配:https://play.golang.org/p/_ameESD2-o)。 – Kaedys
哦,而另一个答案也避免了重复分配(Fabien在OP中提到你的版本中有这样的评论)。然而,另一个答案是在'make()'调用中将slice的长度设置为'countOfLuckyNums',而Fabien的版本则分配一个具有该大小的底层数组,但保留片段长度为0.这对于您来说可能很重要出于某种原因,尽早中断追加序列。例如:https://play.golang.org/p/bIs1jmEhrp – Kaedys
更有效率如何?你只是想跳过tmp变量? https://play.golang.org/p/XKg4VouoUI – JimB