初始化和归零之间的区别,以及GoLang中的new()和make()

Tar*_*rik 7 go

我来自C#背景,我对GoLang初始化和归零定义的方式感到困惑.我想你能猜到这混乱产生make()new()功能定位.当这些方法运行时,我应该在内部发生什么?初始化和归零发生时会发生什么?

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

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

更新

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

Tar*_*rik 7

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

make()new()

我想我现在明白了make()和之间的区别new().起初,它有点混乱,但在这里我得到了:

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

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

那么当你使用new()过切片时会发生什么呢?简单:由于底层数组将是nil,切片将指向一个nil数组.

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

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
Run Code Online (Sandbox Code Playgroud)

make(),在另一方面,是这样的slice,mapchannelS:

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){}
}
Run Code Online (Sandbox Code Playgroud)

初始化与归零

简单来说,归零是一种初始化形式.起初,我认为他们不同,但事实并非如此.初始化是一个更普通的术语,而如果要设置的字段的结构的(属性等)或其类型默认诸如可变0,nil,"",false等等,那么这被称为零位调整.但是,你可以,例如,使用复合字面一样hello := Hello{name="world"},这类似于var hello = new Hello() {Name = "World"}在C#中,那么你初始化Hello一个对象name设置为场world.

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

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

在此输入图像描述

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

  • new 不会将任何内容归零,它只是返回一个指向类型的指针,默认情况下所有类型都归零:`var t Type` 归零,`t := &amp;Type{}` 或 `var t Type; ptr := &amp;t` 与 `t := new(Type)` 相同,但在 new 返回指针之前将类型归零。 (2认同)

One*_*One 5

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

intPtr := new(int)
// or
var i int
intPtr := &i
Run Code Online (Sandbox Code Playgroud)

make 用于初始化通道,切片和贴图.

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

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

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