Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between initialization and zeroing, and new() and make() in GoLang

Tags:

go

I am coming from C# background, and I am little confused with the way of GoLang initialization and zeroing definitions. I think you can guess that this confusion arises from make() and new() functions in Go. What should I expect happening internally when these methods run? What happens when initialization and zeroing happens?

I know that there is an init() function in GoLang that is used to initialize packages. But I think it is different than this.

Anyways, what is the difference between them?

Update

I answered my own question, please check it to see my answer.

like image 704
Tarik Avatar asked May 13 '16 23:05

Tarik


People also ask

What is the difference between make and new in Golang?

New does not initialize the memory, it only zeros it. It returns a pointer to a newly allocated zero value. Make creates slices, maps, and channels only, and it returns them initialized.

What is the use of make in Golang?

In Golang, make() is used for slices, maps, or channels. make() allocates memory on the heap and initializes and puts zero or empty strings into values. Unlike new() , make() returns the same type as its argument. Slice: The size determines the length.

What does New do in Golang?

New() Function in Golang is used to get the Value representing a pointer to a new zero value for the specified type. To access this function, one needs to imports the reflect package in the program.


1 Answers

I think I have figured it and decided to share what I figured so far.

make() vs. new()

I think I now understand the difference between make() and new(). At first, it was little confusing, but here what I got:

new is simply like new in C# or Java, but since there is no constructor in Go, all the fields (like in Java and C# terminology) will be zeroed. Zeroing means more like defaulting the fields. So if the field type is int, then it will be 0, or if it is a struct, then it will be defaulted to nil, and "" for string types. It is actually similar to C# and Java when there is only parameterless constructor available and you are not setting the members to something else manually.

However, types like map, slice, and channels are different. They are different because they are actually wrapper types that wrap an array type to hold the values behind the scenes. So something like List<T> or ArrayList in C# and Java. But using new is not enough in this situation, because the underlying array should be initialized to an empty array to be usable. Because you cannot add or remove from a field of type array which is nil (or null). Therefore, they provided a make() method to help you to initialize slices and such.

So what happens when you use new() over slices, for instance? Simple: Since the underlying array will be nil, the slice will be pointing at a nil array.

So new() would look like the following C#/Java code:

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(), on the other hand, would look like this for slice,map, and channels:

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){}
}

Initialization vs. Zeroing

Simply speaking, zeroing is a form of initialization. At first, I thought they were different but they are not. Initialization is a more general term, whereas if you are set the fields (properties, etc.) of a struct or a variable to its type default such as 0, nil, "", false, etc., then this is called zeroing. However, you can, for instance, use Composite Literals like hello := Hello{name="world"}, which is similar to var hello = new Hello() {Name = "World"} in C#, then you initialize your Hello object with a name field set to world.

In C#, at the time you say new List<string>(), [the underlying array field is initialized to a new array], and make) is performing a similar operation behind the scenes but as a language construct (built in the language itself):

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

enter image description here

So new does zeroing and returns a pointer back. Whereas make() initializes to underlying array to an array with default values for each element and returns the value itself rather than a pointer.

like image 138
Tarik Avatar answered Dec 07 '22 22:12

Tarik