new() and make() in GoLang

  sonic0002        2023-11-18 13:43:25       1,547        0    

GoLang is a modern, statically typed, compiled programming language designed for building scalable, concurrent, and efficient software. It provides various built-in functions and features that help developers write concise and efficient code. Among them are the new() and make() functions, which may appear similar at first glance but serve different purposes in GoLang and are crucial for memory allocation and data initialization.

In this blog article, we will explore the differences between the new() and make() functions, and understand when and how to use them effectively.

new() and make()

new() and make() are both built-in functions in GoLang used for memory allocation. However, they are used for different data types and scenarios:

new() function

new() is used to allocate memory for value types such as integers, floating-point numbers, and structs, and returns a pointer to the newly allocated zero value.

It takes a single parameter which is the type and returns a pointer to that type.

make() function

make() is used to create and initialize slices, maps, and channels, which are reference types in GoLang.

It takes two or three parameters depending on the type and returns an initialized(non-zero value) that is ready to be used.

Understanding the new() function

The syntax for the new() function is very simple, as shown below:

func new(Type) *Type

Here, Type represents the type of value for which we want to allocate memory. Let's look at an example of how to use new().

In this example, we use new() to create a new instance of the Person struct and then assign values to its fields using pointers.

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    // Using new() to allocate memory for a Person struct
    p := new(Person)

    fmt.Printf("%T\n", p)

    // Accessing struct fields using the pointer
    p.Name = "Alice"
    p.Age = 30

    // Displaying the values
    fmt.Println("Name:", p.Name)
    fmt.Println("Age:", p.Age)
}

The output would be

*main.Person
Name: Alice
Age: 30

Understanding the make() function

The syntax of the make() function depends on the type it is used for.

For slices

func make([]Type, len, cap) []Type
  • Type: The type of elements that the slice will hold.
  • len: The initial length of the slice.
  • cap: The capacity of the slice, which is optional and used to specify the capacity of the underlying array. If not provided, it defaults to the same as the length.

Here's an example of creating a slice using make():

package main

import "fmt"

func main() {
    // Using make() to create a slice of integers
    numbers := make([]int, 5, 10)

    // Displaying the slice's length, capacity, and values
    fmt.Println("Length:", len(numbers))
    fmt.Println("Capacity:", cap(numbers))
    fmt.Println("Values:", numbers)

    // Using make() to create a slice of integers
    numbersWithoutOptional := make([]int, 5)

    // Displaying the slice's length, capacity, and values
    fmt.Println("Length:", len(numbersWithoutOptional))
    fmt.Println("Capacity:", cap(numbersWithoutOptional))
    fmt.Println("Values:", numbersWithoutOptional)
}

The output would be

Length: 5
Capacity: 10
Values: [0 0 0 0 0]
Length: 5
Capacity: 5
Values: [0 0 0 0 0]

For map

func make(map[KeyType]ValueType, initialCapacity int) map[KeyType]ValueType
  • KeyType: The type of keys in the map.
  • ValueType: The type of values associated with the keys.
  • initialCapacity: The initial capacity of the map. This is optional but can be used to optimize performance when the number of elements is known in advance.

Here's an example of creating a map using make():

package main

import "fmt"

func main() {
    // Using make() to create a map of string keys and int values
    scores := make(map[string]int)
    // Adding values to the map
    scores["Alice"] = 95
    scores["Bob"] = 87
    // Displaying the map
    fmt.Println("Scores:", scores)
}

The output would be 

Scores: map[Alice:95 Bob:87]

For channel

func make(chan Type, capacity int) chan Type
  • Type: The type of values that can be sent and received through the channel.
  • capacity: The buffer size of the channel. If set to 0, the channel is unbuffered.

Here's an example of creating a channel using make():

package main

import (
    "fmt"
    "time"
)

func main() {
    // Using make() to create an unbuffered channel of integers
    ch := make(chan int)
    // Sending data into the channel using a goroutine
    go func() {
        for i := 1; i <= 5; i++ {
            ch <- i
            time.Sleep(time.Second) // Simulating some work before sending the next value
        }
        close(ch)
    }()
    // Receiving data from the channel
    for num := range ch {
        fmt.Println("Received:", num)
    }
}

The output would be

Received: 1
Received: 2
Received: 3
Received: 4
Received: 5

Conclusion

In this blog article, we unraveled the mystery of the new() and make() functions in GoLang and explained their differences and use cases. To summarize:

  • Use new() to allocate memory for value types and obtain a pointer to the zero value.
  • Use make() to create and initialize slices, maps, and channels(reference types), specifying their type and initial capacity.

Understanding the difference between new() and make() is crucial for efficient memory allocation and data initialization in GoLang. Using these functions correctly will result in cleaner and optimized code in your GoLang projects. Happy coding!

NEW  GOLANG  MAKE 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

long long long is too long

int main(){    long long long int X;    return 0;} The above code compiled with GCC will produce the error above. This is one of the most interesting error messages produced by GCC.