- Published on
Pointer
- Authors
- Name
- Moch Lutfi
- @kaptenupi
Pointers gave me some nostalgic moment when learning C++ on first semester. They become a source of headaches on my day. Pointers are one of the main tools to achieve high-performance code in non-garbage-collected languages. So what about pointers in Go? Luckily Go’s pointer has achieved the best of both worlds by providing high-performance pointers with garbage-collector capabilities and easiness.
Pointers in real world
Unconsciously we already know the main concept of pointers in the real world. Nowadays online markets are popular, we’d like to shopping using a smartphone or computers. After checkout, if you want to receive the package in your house, it’s far easier to simply send the address of your house(pointer) instead of sending the entire house to the seller so that your package is deposited inside. The problem is if you send the wrong address of yours. You will not get the package.
Let’s back to the programming world. For example, I have a simple program to convert mp3 files to another format. In the first step, I must read the mp3 files and save to the variable, let’s say the variable size is 1GB and I need to pass it to another function. Without a pointer, the entire variable is cloned to the scope of the function that is going to use it. So I will have 2GB of memory occupied by using this variable twice. If the second function will pass again to another function, the memory occupied will raise.
If I use a pointer to pass a very small reference to another function so that just the small reference is cloned and I can keep memory usage low.
Different from C or C++ pointers, in GO very limited. We can’t use pointer arithmetic nor can we create a pointer to reference an exact position in the stack.
Here the basic of Example of pointers:
_33package main_33_33import (_33 "fmt"_33 "unsafe"_33)_33_33type Music struct {_33 SongName string_33 TrackNo int_33 Singer string_33}_33_33func main() {_33 // declare a variable_33 music := Music{"November Rain", 20, "Gun n Roses"}_33 // set pointer of music to variable p_33 p := &music_33 fmt.Printf("music data %v\n", music)_33 fmt.Printf("Pointer of music %p\n", p)_33 // access original value using pointer_33 fmt.Printf("Get music from pointer %v\n", *p)_33_33 fmt.Printf("Original size: %T, %d\n", music, unsafe.Sizeof(music))_33 fmt.Printf("Pointer size: %T, %d\n", p, unsafe.Sizeof(p))_33}_33_33// output:_33// music data {November Rain 20 Gun n Roses}_33// Pointer of music 0x10444240_33// Get music from pointer {November Rain 20 Gun n Roses}_33// Original size: main.Music, 20_33// Pointer size: *main.Music, 4
music := Music{"November Rain", 20, "Gun n Roses"}
code represent our 1GB variable and p
contains the reference with value 0x10444240
(represented by an ampersand). We can use asterisk *
to take value from referenced by the pointer. With that example we have an original size of music data is 20 bytes and pointer only 4 bytes. Pointer size has the same size as int variable in Go. Even if I increase the size of the struct/variable the pointer remains the same size.
I hope you can understand. See ya on the next post…