golang ยท go

Difference between make() and new() in Go Lang

Background for C# and Java Developers

Go has constructs like slices, maps, and channels. Slices are similar to collections in C# and maps are basically just maps, which is also known as dictionaries.

Go supports two built-in functions that help developers to initialize their objects: new and make(). new is simply like new in C# or Java, but since there is no constructor in Go, all the fields will be zeroed.

Zeroing

Zeroing means setting the fields to their default values. So if the field type is int, then its default value 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. Samples codes follow in the next sections.

Why make()?

However, types like map, slice, and channels are different. They are different because they are wrapper types that wrap their underlying types which they use to hold the values behind the scenes. So like languages in C# or Java, It would be similar to List<T> or ArrayList that use an array as their underlying data structure. However, if you want to get a workable array or map object in Go, using new is not enough, because the underlying array should be initialized to an empty array to be usable. If you do not set the underlying array to an empty array, you will be working with a nil value and add or removing items to/from it will throw an exception. 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.
  // Imagine doing this set operation in the `make()` method, though.
   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 also a form of initialization. At first, you may think that they are different, but they are not. Initialization is a general term. If you set the fields of a struct or a variable to its type’s default value 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.

Summary

new return a pointer to a zeroed value, whereas make() initializes to underlying array to an empty array with default values for each element and returns the value itself rather than a pointer.

I originally shared this post on Stackoverflow.com

Published: