英文:
How to properly init structs in Go inside slices without constructors
问题
Go语言没有构造函数,所以我想知道如何在切片中正确初始化结构体。我很难相信答案会是初始化并复制所有结构体两次。
这是一个示例,其中队列的缓冲区必须是2的幂。
package main
import "fmt"
// minQueueLen is smallest capacity that queue may have.
// Must be power of 2 for bitwise modulus: x % n == x & (n - 1).
const minQueueLen = 16
type Queue[T any] struct {
buf []T
}
func New[T any]() *Queue[T] {
return &Queue[T]{
buf: make([]T, minQueueLen),
}
}
type SomeStruct struct {
q Queue[int]
}
func main() {
someSlice := make([]SomeStruct, 10)
// 现在buf的大小是错误的,因为我们没有使用正确的构造函数进行初始化。
// 初始化这个结构体两次(成千上万次)将非常浪费资源。
fmt.Println("Size of a buf: ", len(someSlice[0].q.buf))
}
以上是一个示例,其中队列的缓冲区必须是2的幂。
英文:
Go doesn't have constructors so I'm wondering how you would properly initialize a struct inside a slice. I have trouble believing that the answer would be to initialize and copy all the structs twice?
package main
import "fmt"
// minQueueLen is smallest capacity that queue may have.
// Must be power of 2 for bitwise modulus: x % n == x & (n - 1).
const minQueueLen = 16
type Queue[T any] struct {
buf []T
}
func New[T any]() *Queue[T] {
return &Queue[T]{
buf: make([]T, minQueueLen),
}
}
type SomeStruct struct {
q Queue[int]
}
func main() {
someSlice := make([]SomeStruct, 10)
// Now buf is the wrong size because we didn't
// get to init it with the proper constructor.
// It would be very wasteful to initialize this
// struct twice (100s of thousands or more).
fmt.Println("Size of a buf: ", len(someSlice[0].q.buf))
}
Here is an example where the buffer of the queue must be a power of 2.
答案1
得分: 0
你从未真正初始化它。分配一个切片只是分配了空间,但并没有初始化各个元素。一旦你有了切片,你可以遍历它并进行初始化:
func main() {
someSlice := make([]SomeStruct, 10)
for i := range someSlice {
someSlice[i].q = *New[int]()
}
fmt.Println("Size of a buf:", len(someSlice[0].q.buf))
}
你也可以这样做:
func (s *SomeStruct) Init() {
s.q = Queue[int]{
buf: make([]int, minQueueLen),
}
}
func main() {
someSlice := make([]SomeStruct, 10)
for i := range someSlice {
someSlice[i].Init()
}
fmt.Println("Size of a buf:", len(someSlice[0].q.buf))
}
英文:
You never really initialized it. Allocating a slice simply allocates the space, but does not initialize individual elements. Once you have the slice, you can loop through it and inialize:
func main() {
someSlice := make([]SomeStruct, 10)
for i:=range someSlice {
someSlice[i].q=*New[int]()
}
fmt.Println("Size of a buf: ", len(someSlice[0].q.buf))
}
You can also do:
func (s *SomeStruct) Init() {
s.q=Queue[int]{
buf: make([]int, minQueueLen),
}
}
func main() {
someSlice := make([]SomeStruct, 10)
for i:=range someSlice {
someSlice[i].Init()
}
fmt.Println("Size of a buf: ", len(someSlice[0].q.buf))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论