How Pointers Work In Go
Tags: go, todayilearned
Published: 2020-04-15 10:23:00

![gopher mascot](https://res.cloudinary.com/devmayor/image/upload/v1586946040/gopher-1.png)

This is my second article since I started learning the go programming language. If you're also getting your feet wet with a statically typed and compiled language like Go for the first time, this article will help you understand the **what** and **why** of pointers.

#### What are pointers?
Pointers, in computer programming, are simply objects that store memory addresses. A _memory address_ is a reference to a specific location in memory. Think of it as physical addresses, you can easily access a particular location on a map if you had the address right? The map here is the computer memory layout where you store variables of different types each referenced by a unique address.



#### Why pointers?
By now you must be wondering what is the significance of pointers. Pointers are particularly useful in repetitive operations like working with iterables or working with multiple copies of the same underlying data. It is much faster and less expensive to copy over a pointer to a variable and also to deference it rather than copying the whole data structure itself. 

Let's say you have an array of 10,000 items and you want to make a duplicate, copying over an array of such size is not only less efficient but will also be significantly slower than copying a memory address. Imagine you had to make up to 3, 4, or even 10 copies, it's starting to look silly.

> **NB**: Dereferencing means fetching the value stored at a memory location by a pointer.

While pointers are not explicitly available in every programming language, a similar concept like the __reference data type__ is used rather than pointers in languages like JavaScript, Java, Python. The benefit of pointers is that it removes the layer of abstraction that comes with references and allows the developer explicit access to memory addresses.

#### Pointers in Go
Go, like C and C++ gives us pointers to work with. The syntax is similar to C but with a little difference. This is how you define a pointer in Go:

![pointers snippet](https://res.cloudinary.com/devmayor/image/upload/v1586940367/pointers-go.png)

In the snippet above, we define a variable called `name` (very thoughtful) and set the value "John Travolta". We also define another variable `pointerToName` which is literally a pointer to the variable `name`. The "&" symbol preceding `name` essentially says: "give me the memory address of this variable". If we print both variables, we see that `name` outputs the value of the variable while `pointerToName` outputs the memory address of the variable `name`.

So how do you dereference (i.e fetch the underlying value of a memory address) a pointer in go? Before we look at the syntax, it's worth noting that go is a pass-by-value language. This means that when we pass variables around (e.g to a function or assigning an existing variable to another variable declaration), the value is copied to a different memory location and is no longer tied to the original copy. If we mutate the duplicate data, the original copy maintains its state.

> This is what is known as _passing by value_. Of course, the opposite happens when you _pass by reference_.
Although, not all data types are passed by value. `Slices`, `maps`, `channels`, `functions` and of course `pointers` are reference types while `ints`, `floats`, `strings`, `bools`, and `structs` are value types. It is worth noting especially when working with structs to build more complex data structures.

Consider the following snippet:

![pointers code snippet](https://res.cloudinary.com/devmayor/image/upload/v1586944080/pointers-go-2.png)

__What's happening here?__ We're simply defining a struct that describes a user with 4 fields. We declare a variable `user1` of type User and set the field values. We declare a new variable `user2` by copying `user1` then we update the age field. From the output of the two variables, we see that the age field remains unchanged for `user1` while `user2` is updated. Moving on, we declare a third variable, wait for it, `user3` and set it to be a _pointer_ to `user1`. Now, we do the same thing by updating the age and isAdmin fields and from the output, we see that these files were updated for both `user1` and `user3`.

> The "*" symbol preceding `user3` in the `fmt.Printf()` function is how we _dereference_ pointers. We're essentially saying: "give me the value stored at this memory address". This is the reverse use case of the "&" symbol.

In conclusion, we can observe that our data structure wasn't mutable by default and we had to explicitly mutate it through pointers which is a good safety measure. This is an introduction to pointers, however, there's more to it like its usage in _receiver functions_ and _double pointers_. You can read more about pointers in Go [here](https://golang.org/doc/effective_go.html#pointers_vs_values) and [here](http://www.golang-book.com/books/intro/8).