【问题标题】:When should `new` be used in Go?什么时候应该在 Go 中使用`new`?
【发布时间】:2011-03-08 22:17:35
【问题描述】:

在原始语言结构中使用似乎毫无意义,因为您无法指定任何类型的值

func main() {
    y := new([]float)
    fmt.Printf("Len = %d", len(*y) ) // => Len = 0
}

对于 stucts 来说,bit 更有意义,但是说 y := new(my_stuct) 和看似更简洁的 y := &my_struct 有什么区别?

并且由于您创建的任何内容都基于这些原语,因此它们将被初始化为所述零值。那么有什么意义呢?你什么时候想使用new()

很抱歉提出一个非常初学者的问题,但文档并不总是那么清楚。

【问题讨论】:

  • "what's the difference between..." new 用于一个类型。 & 用于值

标签: go


【解决方案1】:

您不能将new 用于切片和映射,如您的代码示例中那样,而是必须使用make commandmake([]float, 100)

new(MyStruct)&MyStruct{} 做同样的事情,因为如果你用 & 获取它们的地址,Go 将在堆上分配值。有时代码只是以一种或另一种风格更好地表达它的意图。

Go 没有对构造函数的内置支持,因此通常您会将对 new 的调用包装到一个函数中,例如 NewMyStruct(),它会执行所有必要的初始化。它还可以初始化私有字段或隐藏接口后面的结构,以防止对象的用户直接弄乱其内部。当您在添加/删除/重命名/重新排序字段时不需要更改其所有用户时,通过这种方式发展结构的结构也更容易。

【讨论】:

  • 关于使用新的,我猜这是一个编译器错误,使该代码有效,可编译的代码?还是发生了其他事情?
  • 我想在切片上调用 new 会分配一些东西,但它不是可用的切片。切片和映射需要一些特殊的初始化,而 make 调用就是这样做的。 (我认为某些内置类型需要 make 是语言设计的缺陷,但现在就是这样。也许如果在某些时候添加了泛型或构造函数,则不需要 make。)跨度>
  • 我明白了。所以我想答案是,你没有。
  • 不,您可以在切片和地图类型上使用newnew 将指向的内存初始化为类型的零值(所有类型都有一个零值),对于切片和映射,它是 nil。因此,切片或映射类型上的new 只需创建指向nil 的指针。 x := new([]float)var temp []float; x := &temp 相同
  • 轻微修正。如果指针转义函数,Go 在堆上分配。它通过执行逃逸分析和适当分配来做到这一点。仅使用 new 或 & 运算符不足以导致在堆上分配值
【解决方案2】:

make 仅适用于映射、切片和通道,而像 type{} 这样的复合字面量仅适用于结构、数组、切片和映射。对于其他类型,您必须使用new 来获取指向新分配实例的指针(如果您不想使用更长的var v T; f(&v))。

如果你想初始化一个结构,我想这很有用:

typedef foo struct {
    bar *int
}
v := foo{bar: new(int)}

【讨论】:

    猜你喜欢
    • 2015-05-19
    • 1970-01-01
    • 2013-11-13
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2011-04-15
    • 2017-04-10
    相关资源
    最近更新 更多