DEV Community

Cover image for Go Course: Pointers
Karan Pratap Singh
Karan Pratap Singh

Posted on • Originally published at karanpratapsingh.com

Go Course: Pointers

In this tutorial, we will discuss pointers. So what are Pointers?

Simply defined, a Pointer is a variable that is used to store the memory address of another variable.

pointers

It can be used like this:

var x *T 
Enter fullscreen mode Exit fullscreen mode

Where T is the type such as int, string, float, and so on.

Let's try a simple example and see it in action.

package main import "fmt" func main() { var p *int fmt.Println(p) } 
Enter fullscreen mode Exit fullscreen mode
$ go run main.go nil 
Enter fullscreen mode Exit fullscreen mode

Hmm, this prints nil, but what is nil?

So nil is a predeclared identifier in Go that represents zero value for pointers, interfaces, channels, maps, and slices.

This is just like what we learned in the variables and datatypes section, where we saw that uninitialized int has a zero value of 0, a bool has false, and so on.

Okay, now let's assign a value to the pointer.

package main import "fmt" func main() { a := 10 var p *int = &a fmt.Println("address:", p) } 
Enter fullscreen mode Exit fullscreen mode

We use the & ampersand operator to refer to a variable's memory address.

$ go run main.go 0xc0000b8000 
Enter fullscreen mode Exit fullscreen mode

This must be the value of the memory address of the variable a.

Dereferencing

We can also use the * asterisk operator to value stored in the variable that the pointer points to. This is called dereferencing.

For example, we can access the value of the variable a through the pointer p using that * asterisk operator.

package main import "fmt" func main() { a := 10 var p *int = &a fmt.Println("address:", p) fmt.Println("value:", *p) } 
Enter fullscreen mode Exit fullscreen mode
$ go run main.go address: 0xc000018030 value: 10 
Enter fullscreen mode Exit fullscreen mode

We can not only access it but change it as well through the pointer.

package main import "fmt" func main() { a := 10 var p *int = &a fmt.Println("before", a) fmt.Println("address:", p) *p = 20 fmt.Println("after:", a) } 
Enter fullscreen mode Exit fullscreen mode
$ go run main.go before 10 address: 0xc000192000 after: 20 
Enter fullscreen mode Exit fullscreen mode

I think this is pretty neat!

Pointers as function args

Pointers can also be used as arguments for a function when we need to pass some data by reference.

Here's an example:

myFunction(&a) ... func myFunction(ptr *int) {} 
Enter fullscreen mode Exit fullscreen mode

New function

There's also another way to initialize a pointer. We can use the new function which takes a type as an argument, allocates enough memory to accommodate a value of that type, and returns a pointer to it.

Here's an example:

package main import "fmt" func main() { p := new(int) *p = 100 fmt.Println("value", *p) fmt.Println("address", p) } 
Enter fullscreen mode Exit fullscreen mode
$ go run main.go value 100 address 0xc000018030 
Enter fullscreen mode Exit fullscreen mode

Pointer to a Pointer

Here's an interesting idea...can we create a pointer to a pointer. And the answer is yes! Yes, we can.

package main import "fmt" func main() { p := new(int) *p = 100 p1 := &p fmt.Println("P value", *p, " address", p) fmt.Println("P1 value", *p1, " address", p) fmt.Println("Dereferenced value", **p1) } 
Enter fullscreen mode Exit fullscreen mode
$ go run main.go P value 100 address 0xc0000be000 P1 value 0xc0000be000 address 0xc0000be000 Dereferenced value 100 
Enter fullscreen mode Exit fullscreen mode

Notice how the value of p1 matches the address of p.

Also, it is important to know that pointers in Go do not support pointer arithmetic like in C or C++.

 p1 := p * 2 // Compiler Error: invalid operation 
Enter fullscreen mode Exit fullscreen mode

However, we can compare two pointers of the same type for equality using a == operator.

p := &a p1 := &a fmt.Println(p == p1) 
Enter fullscreen mode Exit fullscreen mode

But Why?

This brings us to the million-dollar question, why do we need pointers?

Well, there's no definite answer for that, and pointers are just another useful feature that helps us mutate our data efficiently without copying a large amount of data.

And can be applied to tons of use cases.

Lastly, I will add that if you are coming from a language with no notion of pointers, don't panic and try to form a mental model of how pointers work.


This article is part of my open source Go Course available on Github.

GitHub logo karanpratapsingh / learn-go

Master the fundamentals and advanced features of the Go programming language

Learn Go

Hey, welcome to the course, and thanks for learning Go. I hope this course provides a great learning experience.

This course is also available on my website and as an ebook on leanpub. Please leave a ⭐ as motivation if this was helpful!

Table of contents

What is Go?

Go (also known as Golang) is a programming language developed at Google in 2007 and open-sourced in 2009.

It focuses on simplicity, reliability, and efficiency. It was designed to combine the efficacy, speed…

Top comments (0)