初始化和归零之间的区别,以及GoLang

时间:2016-05-13 23:43:12

标签: go

我来自C#背景,我对GoLang初始化和归零定义的方式感到困惑。我想你可以猜到这种混淆来自于Go中的make()new()函数。当这些方法运行时,我应该在内部发生什么?初始化和归零发生时会发生什么?

我知道GoLang中有一个init()函数用于初始化包。但我认为这与此不同。

无论如何,它们之间有什么区别?

更新

我回答了我自己的问题,请检查一下,看看我的答案。

3 个答案:

答案 0 :(得分:7)

我想我已经想到并决定分享我到目前为止的想法。

make()new()

我想我现在明白了make()new()之间的区别。起初,这有点令人困惑,但在这里我得到了:

new就像C#或Java中的new一样,但由于Go中没有构造函数,所有字段(如Java和C#术语)都将归零。归零意味着更像是默认字段。因此,如果字段类型为int,则它将为0,或者如果为struct,则默认为nil和{{1} } ""类型。当只有无参数构造函数可用时,它实际上类似于C#和Java,并且您没有手动将成员设置为其他内容。

但是,stringmapslice等类型不同。它们是不同的,因为它们实际上是包装数组类型的包装类型,用于保存幕后的值。所以像C#和Java中的channelList<T>。但是在这种情况下使用ArrayList是不够的,因为底层数组应初始化为空数组才可用。因为您无法在类型为new(或nil)的数组字段中添加或删除。因此,他们提供了null方法来帮助您初始化make()等。

那么当您在切片上使用slices时会发生什么?简单:由于底层数组为new(),因此切片将指向nil数组。

所以nil看起来像下面的C#/ Java代码:

new()
另一方面,

public class Person{ public string Name; public int Age; public Address HomeAddress; } var person = new Person(); Console.WriteLine(person.Name); // "" Console.WriteLine(person.Age); // 0 Console.WriteLine(person.HomeAddress); // null 对于make()slicemap来说会是这样的:

channel

初始化与归零

简单来说,归零是一种初始化形式。起初,我认为他们不同,但事实并非如此。初始化是一个更通用的术语,而如果您将结构或变量的字段(属性等)设置为其类型默认值,例如public class PersonList{ // We are initializing the array so that we can use it. // Its capacity can increase. private Person[] _personList = new Person[100]; public void Add(Person p){} public void Remove(Person p){} public Person Get(int index){} } 0nil""等,然后这称为归零。但是,您可以使用false之类的hello := Hello{name="world"},类似于C#中的var hello = new Hello() {Name = "World"},然后使用Hello初始化name对象字段设置为world

在C#中,当你说new List<string>()时,[基础数组字段被初始化为一个新数组],而make)正在幕后执行类似的操作,但作为一种语言结构(用语言本身构建):

Composite Literals):

http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,cf7f4095e4de7646

因此new进行归零并返回指针。而make()将基础数组初始化为具有每个元素的默认值的数组,并返回值本身而不是指针。

答案 1 :(得分:5)

new返回一个指向该类型的指针,它是在一个步骤中返回指向本机类型的指针的唯一方法(也就是int,float,complex):

intPtr := new(int)
// or
var i int
intPtr := &i

make用于初始化频道,切片和地图。

无论您如何创建变量,所有变量都会在创建时归零。

关于make的规范:https://golang.org/ref/spec#Making_slices_maps_and_channels

关于零值的规范:https://golang.org/ref/spec#The_zero_value

答案 2 :(得分:1)

new(T)为类型T的新项目分配零存储并返回其地址,类型* T的值:它返回指向新分配的类型T的零值的指针,可以使用;它适用于值类型,例如数组和结构。它是 等同于&T {}

make(T)返回类型T的初始化值;它仅适用于3个内置 参考类型:切片,地图和通道。

var p *[]int = new([]int) // *p == nil; with len and cap 0
//or    
p := new([]int)

var v []int = make([]int, 10, 50)
//or
v := make([]int, 10, 50)

//This allocates an array of 50 ints and then creates a slice v with length 10 and capacity 50 pointing
//to the first 10 elements of the array