DEV Community

Cover image for Pointers in Golang (go)
DIWAKARKASHYAP
DIWAKARKASHYAP

Posted on

Pointers in Golang (go)

1. What are Pointers?

A pointer is a variable that stores the memory address of another variable. It essentially "points" to the location of another variable. This is useful for several reasons: it can be more memory efficient, it can allow you to modify the original variable directly, and it's essential for some data structures and algorithms.

2. Declaration and Initialization

In Go, pointers are declared using the * symbol followed by the type of the stored value. For example, a pointer to an int would be *int.

var x int = 10
var p *int      // Declare a pointer to int
p = &x          // Assign the address of x to p
Enter fullscreen mode Exit fullscreen mode

Here, &x retrieves the memory address of x, and p now holds that address.

3. Dereferencing

To get the value stored at a pointer's address, you "dereference" it using the * symbol:

fmt.Println(*p) // Outputs: 10
Enter fullscreen mode Exit fullscreen mode

4. No Pointer Arithmetic

Unlike some languages (like C or C++), Go doesn't allow pointer arithmetic by default. This means you can't do something like p++ to move to the next memory address. This decision was made to keep the language simpler and avoid potential pitfalls and errors.

5. The new Function

Go provides a built-in function called new that creates a variable and returns a pointer to that variable:

ptr := new(int) // Creates an int variable, sets it to 0, and returns a pointer to it
*ptr = 3        // Sets the value stored at ptr to 3
Enter fullscreen mode Exit fullscreen mode

6. Reference Types

Certain types in Go, like slices, maps, and channels, are reference types. This means when you pass them to functions, you're actually passing a reference to the underlying data, not a copy of the data. As a result, modifying them inside a function will modify the original data:

func modifySlice(s []int) {
    s[0] = 100
}

func main() {
    slice := []int{1, 2, 3}
    modifySlice(slice)
    fmt.Println(slice) // Outputs: [100 2 3]
}
Enter fullscreen mode Exit fullscreen mode

7. Use Cases for Pointers

  • Efficiency: Instead of copying large structs or objects, you can pass a pointer.
  • Modifying External Data: When you need to modify a variable defined outside the current scope.
  • Data Structures: Pointers are essential for building many data structures, like linked lists or trees.

8. Safety

Be cautious when working with pointers. Accessing a nil pointer or the wrong memory location can lead to runtime panics. Always ensure pointers are initialized and valid before dereferencing.

var p *int
fmt.Println(*p) // This will panic because p is nil
Enter fullscreen mode Exit fullscreen mode

In conclusion, while pointers in Go provide powerful capabilities, they should be used judiciously. The language has been designed to allow you to get many of the benefits of pointers (e.g., with reference types) without always having to manage them directly.

Thank you for reading. I encourage you to follow me on Twitter where I regularly share content about JavaScript and React, as well as contribute to open-source projects and learning golang. I am currently seeking a remote job or internship.

Twitter: https://twitter.com/Diwakar_766

GitHub: https://github.com/DIWAKARKASHYAP

Portfolio: https://diwakar-portfolio.vercel.app/

Top comments (1)

Collapse
 
dyfet profile image
David Sugar

I think this should include a discussion of pass by value vs pass by reference... this is where pointers become essential to understand in go, and it's well understated in the 2nd use case. I would even say it deserves its own section (9).