在Go语言中,什么时候应该使用`new`关键字?

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

When should `new` be used in Go?

问题

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

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

对于结构体来说,这样做有点意义,但是使用y := new(my_stuct)和看起来更简洁的y := &my_struct之间有什么区别呢?

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

对于这个非常初学者的问题,很抱歉,但是文档并不总是那么清晰。

英文:

It seems pointless to be used in primitive language constructs, as you can't specify any sort of values

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

For stucts it makes a bit more sense, but what's the difference between saying y := new(my_stuct) and the seemingly more concise y := &my_struct?

And since anything you create is based on those primitives, they will be initialized to the said zero values. So what's the point? When would you ever want to use new()?

Sorry for the very-beginner question, but the documentation isn't always that clear.

答案1

得分: 6

你不能像你的代码示例中那样对切片和映射使用new,而是必须使用make命令make([]float, 100)

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

Go没有内置的构造函数支持,所以通常你会将对new的调用封装到一个函数中,例如NewMyStruct(),该函数执行所有必要的初始化。这还使得初始化私有字段或将结构体隐藏在接口后面成为可能,以防止对象的用户直接干扰其内部。此外,当添加/删除/重命名/重新排序字段时,这种方式更容易演变结构体的结构,而不需要更改所有使用它的地方。

英文:

You can't use new for slices and maps, as in your code example, but instead you must use the make command: make([]float, 100)

Both new(MyStruct) and &MyStruct{} do to the same thing, because Go will allocate values on the heap if you get their address with &. Sometimes the code just expresses it intent better in one style or the other.

Go does not have built-in support for constructors, so usually you would wrap the call to new into a function, for example NewMyStruct() which does all the necessary initialization. It also makes it possible to initialize private fields or hide the struct behind an interface, to prevent users of the object from directly messing with its internals. Also evolving the structure of the struct is easier that way, when you don't need to change all of its users when adding/removing/renaming/reordering fields.

答案2

得分: 0

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

我猜这对于初始化结构体是有用的:

type foo struct {
    bar *int
}
v := foo{bar: new(int)}
英文:

make does only work for maps, slices and channels and composite literals like type{} work only for structs, arrays, slices, and maps. For other types, you'll have to use new to get a pointer to a newly allocated instance (if you don't want to use a longer var v T; f(&v)).

I guess this is useful if you want to initialize a struct:

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

huangapple
  • 本文由 发表于 2010年6月28日 06:06:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/3129068.html
匿名

发表评论

匿名网友

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

确定