DEV Community

Cover image for Mastering Pointers in Go: An In-Depth Guide to Efficient Data Manipulation
Avinash Chodavarapu
Avinash Chodavarapu

Posted on

Mastering Pointers in Go: An In-Depth Guide to Efficient Data Manipulation

When diving into the Go language, using pointers is often one of the more complicated and confusing concepts for beginners. However, they are an important aspect of the Go type system, providing powerful tools for memory management and data manipulation. This blog post clarifies the purpose and usage of pointers in Go with clear examples.

What are Pointers?

All about pointers in Go Language
In its simplest sense, a pointer is a variable that stores the memory address of another variable. Instead of storing the actual value of the variable, it contains an "address" where that value is stored in memory. This concept isn't unique to Go, it's also widely used in other languages like C and C++.

Lets understand pointers with some real life example. Consider a library, it is filled with various books. Each book can be considered a variable with a one of a kind substance (esteem). Presently, to get to a particular book, you utilize the library's catalog, which gives you the area of the book - which rack it's on, what row, and what position. This catalog is like a pointer. It doesn't contain the actual substance of the book (the data), but it does hold the information about how to discover that book (the memory address of the data).

Let's see how operations with pointers work in this context:

Declaring a Pointer: It's like having an empty entry in your catalog where you can enter the location of your new book.

Assigning a Pointer: This is the same as entering the exact location of the book in your catalog.

Dereferencing a Pointer: This is similar to using catalog entries to find a book and read its contents.

Changing Values via Pointers: Suppose you want to replace one book in the same place with another. First use the catalog (pointer) to find the location, then replace the book (value). In the catalog, the position (pointer) does not change, but the contents of the workbook (memory address value) change.

I hope this real-life example helps simplify the concept of pointers for you!

Declaring Pointers :

In Go, a pointer is declared using the * symbol followed by the type of the stored value. For instance, a pointer to an integer is written as *int, and a pointer to a string is written as *string.

var p *int
var q *string
Enter fullscreen mode Exit fullscreen mode

In this code, p and q are pointers to an int and a string, respectively. But, they are uninitialized, and thus, they point to nil.

Using Pointers :

The power of pointers shines when we start using them to reference and manipulate variables. The & operator is used to get the address of a variable.

Let's illustrate this:

x := 5
p := &x
fmt.Println(p) // Outputs: 0xc0000160b8 (this will differ each run)

Enter fullscreen mode Exit fullscreen mode

Here, p is a pointer to x. It stores the memory address of x. The actual address will vary each time you run the program.

Dereferencing Pointers :

To get the value stored at a particular memory address, we dereference the pointer. This is achieved by prefixing the pointer variable with the * operator. This process is known as 'dereferencing.'

x := 5
p := &x
fmt.Println(*p) // Outputs: 5

Enter fullscreen mode Exit fullscreen mode

In the above example, *p gives us the value stored at the memory location p is pointing to, which is 5.

Changing Values via Pointers :

One of the primary uses of pointers is to manipulate data directly in memory. Since a pointer stores a variable's address, changing the data at that address changes the value of the original variable.

x := 5
p := &x
*p = 10
fmt.Println(x) // Outputs: 10

Enter fullscreen mode Exit fullscreen mode

Here, *p = 10 changes the value at the memory address that p points to. Since p points to x, the value of x changes to 10.

Pointers in Functions :

Pointers become incredibly handy when working with functions. They allow functions to modify variables directly, leading to efficient memory usage. Without pointers, Go passes values to functions by value, meaning a copy of the value is made, leaving the original value unchanged.

func change(val int) {
    val = 10
}

x := 5
change(x)
fmt.Println(x) // Outputs: 5

Enter fullscreen mode Exit fullscreen mode

In the above example, the function change doesn't alter x because Go passes x by value,

not by reference.

To change x directly, we use pointers:

func change(val *int) {
    *val = 10
}

x := 5
change(&x)
fmt.Println(x) // Outputs: 10

Enter fullscreen mode Exit fullscreen mode

Now, the function change modifies x directly through its memory address. This principle is extremely useful for manipulating large structures, as it helps avoid unnecessary data duplication and makes your code more efficient.

Conclusion :

Whereas the concept of pointers could appear a bit overwhelming at first, they offer a capable tool for managing and manipulating data within Go. By understanding how to declare, use, and dereference pointers, you'll tackle the control of direct memory access to create your Go programs more proficient and adaptable.

Top comments (2)

Collapse
 
go_backend profile image
Campus Placement Solution

just to add on this :
passing pointers to functions is fine but we should avoid returning pointers from functions as those will increase your heap memory and consequently GC scans and ultimately over the time your program will get slower .

Collapse
 
avinashtechlvr profile image
Avinash Chodavarapu

Yes, thank you for adding it next time will add these things too 😊