在 Go 中实例化类型的首选方法

我喜欢 Go 没有给我一百万种方法来做简单的事情——借用 Python 之禅,“应该有一种——最好只有一种——明显的方法来做这件事。”


但是,我不清楚实例化类型的首选/惯用方式。基本类型很简单:


n := 0

t := 1.5

str := "Hello"

但是结构呢?以下是否等价,如果是,哪个更受欢迎,为什么?


var f Foo    

f := Foo{}

切片呢?我可以做var xs []int, xs := []int{}, or xs := make([]int),但我认为第一个选项(与结构相反)与其他选项不同?我认为这也适用于地图。


有了指针,我听说new应该避免这种情况。这是一个很好的建议,如果是这样,什么可以算作 的有效用法new?


我意识到这在一定程度上可能是风格问题,但在任何情况下,偏好特定风格的理由都会有所帮助。


狐的传说
浏览 256回答 3
3回答

元芳怎么了

当你声明一个变量时, whereT是某种类型:var name TGo 给你一块未初始化的“归零”内存。对于原语,这意味着var name int它将是 0,并且var name string将是“”。在C 中,它可能被归零,或者可能是出乎意料的。Go 保证未初始化的变量是该类型的零等价物。在内部,切片、映射和通道被视为指针。指针零值为零,意味着它指向零内存。如果没有初始化它,如果您尝试对其进行操作,您可能会遇到恐慌。该make函数是专门为切片、贴图或通道设计的。make 函数的参数是:make(T type, length int[, capacity int]) // For slices.make(T[, capacity int]) // For a map.make(T[, bufferSize int]) // For a channel. How many items can you take without blocking?切片length是它以多少个项目开头。容量是在需要调整大小之前分配的内存(内部,新大小 * 2,然后复制)。有关更多信息,请参阅Effective Go:使用 make 分配。结构:new(T)等价于&T{},而不是T{}。*new(T)相当于*&T{}。切片:make([]T,0)相当于[]T{}.地图:make(map[T]T)相当于map[T]T{}.至于首选哪种方法,我问自己以下问题:我现在知道函数内的值吗?如果答案是“是”,那么我会选择上述之一T{...}。如果答案是“否”,那么我使用 make 或 new。例如,我会避免这样的事情:type Name struct {    FirstName string    LastName string}func main() {    name := &Name{FirstName:"John"}    // other code...    name.LastName = "Doe"}相反,我会做这样的事情:func main() {    name := new(Name)    name.FirstName = "John"    // other code...    name.LastName = "Doe"}为什么?因为通过使用new(Name)我明确表示我打算稍后填充这些值。如果我使用&Name{...}它就不清楚我打算稍后在同一函数中添加/更改值而不阅读其余代码。当您不需要指针时,结构是例外。我将使用T{},但如果我打算添加/更改值,我不会在其中添加任何内容。当然*new(T)也有效,但这就像使用*&T{}. T{}在这种情况下更干净,尽管我倾向于使用带有结构的指针来避免在传递时进行复制。另一件要记住的事情是, a[]*struct比 更小,调整大小更便宜[]struct,假设结构比指针大得多,指针通常为 4 - 8 个字节(64 位上为 8 个字节?)。

慕斯王

您可以查看 Go 标准库源,在那里您可以找到许多惯用的 Go 代码。您是对的:var xs []int与其他两个变体不同,因为它不“初始化”xs,xs 为零。而另外两个确实构造了一个切片。xs := []int{}如果您需要一个零上限的空切片,则很常见,同时make为您提供更多选择:长度和容量。另一方面,通常从一个 nil 切片开始并通过附加来填充var s []int; for ... { s = append(s, num) }。new完全无法避免,因为它是创建指针的唯一方法,例如指向 uint32 或其他内置类型。但你是对的,写作a := new(A)是非常罕见的,主要是a := &A{}因为这可以变成a := &A{n: 17, whatever: "foo"}. 使用 ofnew并不是真的不鼓励,但考虑到结构文字的能力,对我来说它只是 Java 的遗留物。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go