如何在Go语言中正确初始化切片中的结构体,而不使用构造函数。

huangapple go评论75阅读模式
英文:

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

huangapple
  • 本文由 发表于 2022年3月3日 11:01:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/71331633.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定