Have you ever wondered how a program remembers where a value lives in memory, even when the value itself keeps changing? That mystery is solved through pointers, one of the most powerful yet confusing concepts for many Golang beginners. If you’ve written Go code but never truly understood what happens under the hood when variables are passed around, stored, or modified, then pointers are the missing piece in your toolkit.
Pointers in Go give you direct memory access, allowing your programs to run faster, use fewer resources, and manipulate data more efficiently. They may look intimidating at first glance, but once you grasp how they work, the way you write Go code will transform completely. In this guide, we’ll break down pointers step-by-step, use practical examples, and show you why understanding them is essential for becoming a confident Go developer.
What are Pointers in Go?
Pointers are among the strongest and foundational features of the Golang programming language. They let you manipulate memory directly, make dynamic data structures and improve program efficiency. Even though pointers can also be kind of tricky to use and incorrect usage can lead to memory leaks and other errors as well. Now, let us know more about what are pointers in Go through an example.
package main
import "fmt"
func main() {
// Declare a variable
x := 10
// Declare a pointer to x
p := &x
// Print the value of x and the pointer
fmt.Println("Value of x:", x) // Output: 10
fmt.Println("Address of x:", p) // Output: memory address (e.g., 0xc0000140a0)
fmt.Println("Value at p:", *p) // Output: 10 (dereferencing the pointer)
// Modify x through the pointer
*p = 20
fmt.Println("New value of x:", x) // Output: 20
}
|
Here is the explanation to this example:
- Variable x: Stores the value 10.
- Pointer p: Made with &x, it holds the memory address of x.
- Dereferencing *p: Accesses the value at the address stored in p, which is initially 10.
- Modifying via pointer: Setting *p = 20 changes the value at the address p points to, so x becomes 20.
Main Points:
- & gets the address of a variable.
- * gets or sets the value at that address.
- Pointers allow you to modify a variable indirectly by referencing its memory location.
As we can see, this example shows exactly how pointers work in Go for reference and refining the data.
What are Go Pointer Variables?
As we read above on what are Go pointers, let us now understand what are Go pointer variables. These are special variables which store the memory address of another variable, rather than the variable’s value directly. The Go pointer variables act as references to the location in memory where a value is stored. Now, let us deeply understand the Go pointer variables with an example, so it's easy for you to understand. For instance-
package main
import "fmt"
func main() {
// Declare a variable
num := 42
// Declare a pointer variable
ptr := &num
// Print values
fmt.Println("num value:", num) // Output: 42
fmt.Println("ptr address:", ptr) // Output: memory address (e.g., 0xc0000140b0)
fmt.Println("Value at ptr:", *ptr) // Output: 42
// Change value via pointer
*ptr = 100
fmt.Println("Updated num:", num) // Output: 100
}
|
Now let us understand what this example is trying to tell us:
- Variable num: It holds the integer value 42.
- Pointer variable ptr: Declared with &num, it stores the memory address of num.
- Dereferencing *ptr: It retrieves the value at the address stored in ptr which is 42.
- Modifying via pointer: Setting *ptr = 100 updates the value at the address, so num changes to 100.
Main points to Remember:
- & gets the memory address of a variable.
- Here, * accesses or modifies the value at that address.
- Pointers allow indirect manipulation of variables through referencing their memory location.
This example shows how pointer variables work in Go for referencing and updating data.
How to Declare a Pointer?
So now, the question arises, how to declare a pointer? You need to specify the data type the pointer will point to, which is followed by an asterisk (*) and then the pointer’s name. For instance, int *ptr; declares ptr as a pointer which can hold the memory address of an integer variable. The asterisk (*) is the indirection operator and shows that the variable being declared is a pointer. Now, let us understand it even more properly through an example. So, here it goes-
package main
import "fmt"
func main() {
// Declare a variable
age := 25
// Declare a pointer to age
agePtr := &age
// Print details
fmt.Println("age value:", age) // Output: 25
fmt.Println("agePtr address:", agePtr) // Output: memory address (e.g., 0xc0000140c0)
fmt.Println("Value at agePtr:", *agePtr) // Output: 25
}
|
The explanation of the above example:
- Variable age: An integer variable initialized with the value 25.
- Pointer declaration agePtr:= &age:
i) Here, &age creates a pointer to the memory address of age.
ii) And, agePtr is a pointer variable that holds this address.
- Dereferencing *agePtr: The * operator retrieves the value stored at the address held by agePtr, which is 25.
Main Points to Remember:
- Make use of & to get the memory address of a variable when declaring a pointer.
- Put * to use for accessing the value at the pointer's address.
- Syntax: var pointerName *Type = &variable or make use of short declarations as shown.
The above given example shows how to declare a pointer in Golang and access the value it points to.
How to Initialize Pointers in Go?
Now, let us understand how to initialize pointers in Go. It includes assigning a memory address to a pointer variable. This lets the pointer ‘point’ to a particular location in memory, basically where another variable’s data is preserved. Now, let us understand this properly with an example, to make things easier for you to understand. Here it is-
package main
import "fmt"
func main() {
// Declare and initialize a variable
score := 85
// Initialize a pointer to score
scorePtr := &score
// Print details
fmt.Println("score value:", score) // Output: 85
fmt.Println("scorePtr address:", scorePtr) // Output: memory address (e.g., 0xc0000140d0)
fmt.Println("Value at scorePtr:", *scorePtr) // Output: 85
}
|
Now, let us understand what this means:
- Variable score: Initialized with the value 85.
- Pointer initialization scorePtr:= &score:
i) &score gets the memory address of score.
ii) scorePtr is a pointer variable initialized to hold this address.
- Dereferencing *scorePtr: The * operator accesses the value at the address stored in scorePtr that is 85.
Main Points to Remember:
- Initialize a pointer using & to reference the address of an existing variable.
- Syntax: var pointerName *Type = &variable (or use short declaration pointerName := &variable).
- A pointer must be initialized with a valid address (e.g., &variable) to avoid errors like accessing a nil pointer.
This example represents how to initialize a pointer in Go to point to a variable's memory address.
Read Also: Top 50+ Golang Interview Questions And Answers
Go Pointer Examples (5)
Here are the 5 short, easy to understand examples of pointers in Go, each one of them are given with their brief explanation to make things easier for you to understand. Every example given below shows a different aspect of making use of the pointers. So let’s start!
Example 1: Basic Pointer Declaration and Dereferencing
package main
import "fmt"
func main() {
x := 10
p := &x // Initialize pointer to x
fmt.Println("x:", x) // Output: x: 10
fmt.Println("p:", p) // Output: p:
fmt.Println("*p:", *p) // Output: *p: 10
}
|
Here is an explanation to the above example-
- x is an integer variable with value 10.
- p := &x initializes a pointer p to the address of x.
- *p dereferences the pointer to get the value at the address (10).
This shows how to declare a pointer and access the value it points to.
Example 2: Modifying Value via Pointer
package main
import "fmt"
func main() {
num := 20
ptr := &num // Pointer to num
*ptr = 30 // Modify value via pointer
fmt.Println("num:", num) // Output: num: 30
}
|
Here is an explanation to the above example-
- ptr is initialized to point to num’s address.
- *ptr = 30 changes the value at the address to 30, updating num.
This shows how pointers allow indirect modification of a variable’s value.
Example 3: Pointer to a Zero Value
package main
import "fmt"
func main() {
var x int // Zero value (0)
p := &x // Pointer to x
fmt.Println("*p:", *p) // Output: *p: 0
*p = 50
fmt.Println("x:", x) // Output: x: 50
}
|
Here is an explanation to the above example-
- x is an uninitialized integer (defaults to 0 in Go).
- p := &x points to x’s address.
- Dereferencing *p shows 0, and assigning *p = 50 updates x to 50.
This shows pointers work with zero-valued variables.
Example 4: Passing Pointer to a Function
package main
import "fmt"
func updateValue(p *int) {
*p = 100 // Modify value at pointer
}
func main() {
val := 42
updateValue(&val) // Pass pointer to val
fmt.Println("val:", val) // Output: val: 100
}
|
Here is an explanation to the above example-
- updateValue takes a pointer *int as a parameter.
- Passing &val allows the function to modify val’s value via the pointer.
- *p = 100 changes val to 100.
This shows how pointers enable functions to modify variables outside their scope.
Example 5: Nil Pointer
package main
import "fmt"
func main() {
var p *int // Pointer not initialized
if p == nil {
fmt.Println("p is nil") // Output: p is nil
}
x := 15
p = &x // Initialize pointer
fmt.Println("*p:", *p) // Output: *p: 15
}
|
Here is an explanation to the above example-
- p is declared as a pointer (*int) but not initialized, so it’s nil.
- Checking p == nil confirms it points to nothing.
- Assigning p = &x initializes it to point to x’s address, and *p accesses x’s value (15).
This shows the importance of initializing pointers to avoid nil pointer errors.
Points to Remember:
- Make use of & to get a variable’s address and initialize a pointer.
- Use * to dereference a pointer (access or modify the value at the address).
- Pointers are useful for modifying variables indirectly, especially in functions.
- Always ensure a pointer is initialized to avoid accessing a nil pointer.
These examples cover all the basics of declaring, initializing, and using pointers in Go.
Wrapping Up
Go pointers give a strong way to handle memory and manipulate data indirectly, permitting efficient variable modifications and function operations. Through using & to get addresses and * to access or update values, developers can write flexible and performant code. Though, care must be taken to initialize pointers properly to avoid nil pointer errors. Mastering pointers in Go enhances your ability to build robust applications with precise control over data.
FAQs: Pointers in Go
Q1. What are dangling pointers?
These pointers continue to reference a memory location which has been deallocated or is no longer valid.
Q2. Why use pointers?
They are for storing memory addresses, allowing efficient memory management, strong memory allocation and direct manipulation of data in memory.
Q3. Does Java deal with Pointers?
No, they do not have pointers, as it uses something known as ‘reference’.
Q4. What do * and & mean in Go?
In Go, & is used to get the memory address of a variable and * is used to get the value from that address.
Course Schedule