Let's Go Pointer
Tags: go, pointer
Published: 2021-07-30 15:20:24

## Pre-requisite
---
- I assume that you have installed and configured Go in your machine
- I assume you want to learn about pointer especially in Go
- I advice you to clone my repository
```bash
git clone https://github.com/codewithdjaeger/go-with-golang.git

cd go-with-golang/pointer
```
## What is this Pointer?

---

Pointer is a special variable. It stores the memory address of where the value is stored instead of the value itself. Simply, it stores the address of someone who has something. So, when the something that is owned by the someone is changed then the value in the pointer also changed.

![pointer concept](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jou0m3qflxdlxtl1k1cv.png)

Someone's address analogically is the memory address. It is always found as a hexadecimal value (e.g. 0xFF etc.), a number starting with 0x is hexadecimal. For the real example, I'll show you this code written in Go Lang.

```go
var someone int = 10
var pointer *int = &someone

fmt.Println("Memory address of someone is", pointer)

// Output:
// Memory address of someone is 0xc000014098
```

From the example above, we know that `pointer` has the value of `&someone` and why would that happen? Despite we know that `someone` is assigned with `10`.  If you notice it already, yes, it is because of that suspicious `&` preceding the variable name and what exactly is it?

## What Exactly Address and Dereferencing Operator Is?

---

It is one of two notations for declaring pointer variables. The `&` notation also called as **address operator** is used to get the memory address of the variable and it is always used preceding its variable name while the other, `*` notation also called as **dereferencing operator**, can be used preceding variable type, as the above example, or preceding its variable name.

If the **address operator** is used to get the memory address of its variable, so, what does the **dereferencing operator** do? Actually, it depends on how you use it. When it preceding variable type, it is used for declaring the pointer variable. While it is preceding its variable name, it is used to access the value that is stored in the memory address.

```go
fmt.Println("Memory address of someone accessed by address operator is", &someone)
fmt.Println("Value of someone accessed by dereferencing operator is", *pointer)

// Output:
// Memory address of someone accessed by address operator is 0xc000014098
// Value of someone accessed by dereferencing operator is 10
```


## What Actually This Pointer Things Do?

---

To answer this question that's bother your head, first, let's take a look at this.

```go
var someone int = 10
var someoneElse int = someone

fmt.Println("Hello, someone's value is", someone)
fmt.Println("And someone else's value is", someoneElse)

someone = 20
fmt.Print("\n")

fmt.Println("Yeay, someone's value is changed to", someone)
fmt.Println("Oh no, someone else's value still", someoneElse)

// Output: 
// Hello, someone's value is 10
// And someone else's value is 10        

// Yeay, someone's value is changed to 20
// Oh no, someone else's value still 10
```

Really? So, what?

Okay, what I want to emphasize from the code above is when `someone`'s value is changed, `someoneElse`'s still, despite it has been assigned with the value of `someone`.

But why? What's wrong with that?

Okay, now take a look at this.

```go
var someone int = 10
var someoneElse *int = &someone

fmt.Println("Hello, someone's value is", someone)
fmt.Println("And someone else's value is", *someoneElse)

someone = 20
fmt.Print("\n")

fmt.Println("Yeay, someone's value is changed to", someone)
fmt.Println("and finally, someone else's value is changed to", *someoneElse)

// Output:
// Hello, someone's value is 10
// And someone else's value is 10

// Yeay, someone's value is changed to 20
// and finally, someone else's value is changed to 20
```

From the last example, both `someone` and `someoneElse` value changed. It is not because of the notation, because it's just used to accessed the value, but it is because the pointer.

The first example show us that `someoneElse` has the value of `someone`, yes, that's right. But, actually despite they have the same value, their address are different as you can see from the example below.

```go
var someone int = 10
var someoneElse int = someone

fmt.Println("Here, someone's memory address is", &someone)
fmt.Println("And someone else's memory address is", &someoneElse)

// Output :
// Here, someone's memory address is 0xc000014098
// And someone else's memory address is 0xc0000140b0
```

Yes, they're pointing to the different memory addresses and that explains why when `someone`'s value is changed, `someoneElse`'s not.


## Are There Any Different Ways to Do Pointer in GO?

---

yes, there are.

Firstly, You must know that Go's compiler is smart enough to determine what type of value is assigned to a variable. So,  you can use shorthand such as `:=` to declare pointer instead of using regular declaration and let the compiler handle the rest. Take a look at the example below. 

```go
someone := 10
someoneElse := &someone

fmt.Println("Here, someone's value is", someone)
fmt.Println("And someone else's value is", *someoneElse)

// Output :
// Here, someone's value is 10
// And someone else's value is 10
```

Also, the array will return a pointer when you assign its slice to a variable like the example below.

```go
someoneArray := []int{1, 2, 3}
someoneElseArray := someoneArray

fmt.Println("Here, someone array's value is", someoneArray)
fmt.Println("And someone else array's value is", someoneElseArray)

someoneArray[0] = 10
fmt.Print("\n")

fmt.Println("Yeay, someone array's value is changed to", someoneArray)
fmt.Println("And also someone else array's value is changed to", someoneElseArray)

// Output :
// Here, someone array's value is [1 2 3]
// And someone else array's value is [1 2 3]

// Yeay, someone array's value is changed to [10 2 3]        
// And also someone else array's value is changed to [10 2 3]
```

Lastly, you may use `new()` to return a pointer while using struct. like the example below.

```go
package main

import "fmt"

type someoneStruct struct {
	value int
}

func main() {
	someone := new(someoneStruct)
	someoneElse := someone

	fmt.Println("Here, someone's value is", someone.value)
	fmt.Println("And someone else's value is", someoneElse.value)

	someone.value = 10
	fmt.Print("\n")

	fmt.Println("Yeay, someone's value is changed to", someone.value)
	fmt.Println("And also someone else's value is changed to", someoneElse.value)
}

// Output :
// Here, someone's value is 0
// And someone else's value is 0

// Yeay, someone's value is changed to 10        
// And also someone else's value is changed to 10
```

## Conclusions

---

- Pointer stores the memory address of a value instead of the value itself.
- To declare the pointer variable you must use **dereferencing operator** (`*`) and **address operator** (`&`).
- In Go, you can use shorthand (`:=`) to declare pointer variable and you can use slice of array or `new()` on a struct to return a pointer.