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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 ornew()
on a struct to return a pointer.
Top comments (0)