DEV Community

Kevin Wasonga
Kevin Wasonga

Posted on

Pointers in Go: An In-Depth Guide to Referencing and DereferencingPointers in Go

In programming, especially in languages like Go, understanding how to manage memory efficiently is crucial. One of the key concepts in this domain is the use of pointers, which allows developers to reference memory addresses rather than the actual data. This guide will explore the concepts of referencing and dereferencing using practical examples, making the abstract idea more concrete.

What are Referencing and Dereferencing?

  • Referencing: This is the process of obtaining the memory address of a variable. When you reference a variable, you essentially point to its location in memory, allowing you to interact with the data at that specific address without duplicating it. This is particularly useful when passing data to functions, as it can reduce memory usage and improve performance.

  • Dereferencing: This is the opposite of referencing. When you dereference a pointer, you access or manipulate the actual value stored at the memory address pointed to by the pointer. Dereferencing allows you to retrieve or change the data in memory directly through the pointer, providing flexibility in managing the variable's value.

Symbols for Referencing and Dereferencing

  1. Referencing with &:

    • Symbol: &
    • Purpose: Used to get the memory address of a variable.
    • Context: Imagine you want to know exactly where a specific resource is stored in a warehouse. By using &, you ask for the location or "address" of that resource rather than the resource itself.
    • Example:
     x := 7        // Define variable x with value 7
     y := &x       // Reference x; y now holds x's memory address
     fmt.Println(y) // Prints x's memory address (e.g., 0xc000018090)
    
  • In this example, y stores the address of x, not the value 7. We’ve used &x to retrieve where x is stored in memory.
  1. Dereferencing with *:

    • Symbol: *
    • Purpose: Used to access the value stored at a specific memory address (or "follow" a reference to get the original data).
    • Context: Going back to our warehouse analogy, dereferencing is like using the directions (address) you have to reach the warehouse and see what’s actually inside. When you dereference, you’re asking to see or use the data that the address points to.
    • Example:
     x := 7          // Define variable x with value 7
     y := &x         // Reference x; y now holds x's memory address
     z := *y         // Dereference y to access x's value
     fmt.Println(z)  // Prints 7, which is the value stored at the address y points to
    
  • Here, *y dereferences y, meaning it accesses the actual value stored at y's address, which is 7.

How Referencing and Dereferencing Work Together

  • Referencing is about finding the "where" — it gives you the address of a variable. This is helpful if you want to pass around where something is stored instead of making a copy of it.
  • Dereferencing is about accessing the "what" — it follows the address to retrieve or modify the actual value.

Practical Example

package main

import "fmt"

func main() {
    x := 10               // Step 1: Define variable x with a value of 10
    y := &x               // Step 2: Reference x with &, assigning x's address to y
    fmt.Println("Address of x:", y) // Step 3: Print x's address (memory location)

    z := *y               // Step 4: Dereference y to get the value at that address
    fmt.Println("Value of x accessed via y:", z) // Prints 10, the value at y’s address

    *y = 20               // Step 5: Change value at y’s address (which is x’s value)
    fmt.Println("Updated value of x:", x) // Prints 20, showing x is updated
}
Enter fullscreen mode Exit fullscreen mode

Explanation of Symbols in the Code:

  1. &x - References x to get its memory address, storing that address in y.
  2. *y - Dereferences y, accessing the value stored at x's memory address.

Output:

Address of x: 0xc000018090
Value of x accessed via y: 10
Updated value of x: 20
Enter fullscreen mode Exit fullscreen mode

In this example, y holds the location of x, and *y (dereferencing y) lets us read or modify x's value directly through that address.

Top comments (0)