Table of contents
In Go, pointers are variables that hold the memory address of another variable. To declare a pointer in Go, we use the *
symbol followed by the type of the value it is pointing to. For example, the following code declares a pointer to an integer variable:
var ptr *int
Pointers in Go have some similarities with pointers in C, but there are also some differences:
Go doesn't allow pointer arithmetic like C. This means you cannot perform arithmetic operations, such as increment or decrement, on a pointer.
Go has garbage collection, so you don't need to manually manage memory like you do in C.
Diagram
This diagram show the pointer p that is contaning the address of variable y with value 2020. Pointer is just a redirectation variable that borrow address from another variable.
Importance of pointers
Pointers are a fundamental concept in Go and they are used heavily in many of the standard packages and functions. In order to understand these packages and functions, it's important to have a good understanding of pointers.
Some of the standard packages in Go that use pointers extensively include:
fmt
: Thefmt
package is used for input and output operations in Go. It uses pointers in many of its functions to modify the values of variables that are passed to it. For example, thefmt.Sprintf()
function returns a formatted string and takes a pointer to an interface as its first argument.sync
: Thesync
package provides basic synchronization primitives such as mutexes, wait groups, and semaphores in Go. These primitives are implemented using pointers to shared variables that are accessed by multiple goroutines.net
: Thenet
package is used for network programming in Go. It uses pointers in many of its functions to pass buffers and addresses between functions.
Understanding pointers is also important when working with Go's built-in reference types such as slices and maps, which are implemented as pointers to underlying data structures. Pointers are used to modify the underlying data in these reference types, and not understanding pointers can lead to confusion when trying to modify or manipulate these data structures.
Use-Cases
Here are some use-cases where pointers in Go are useful:
Passing large structs to functions: When you pass a struct to a function in Go, a copy of the struct is created. This can be a problem if the struct is large, as copying it can be expensive in terms of time and memory. By passing a pointer to the struct, you can avoid making a copy and the function operates directly on the original struct.
// simple example of passing pointer to struct to function type Person struct { name string age int } func updateAge(p *Person, newAge int) { p.age = newAge } func main() { person := Person{name: "John", age: 30} updateAge(&person, 35) // Pass pointer to struct fmt.Println(person) // Person{name: "John", age: 35} }
Modifying values in a function: If you want to modify the value of a variable inside a Go function and have the changes reflected outside of the function, you need to pass a pointer to the variable.
// simple example of modifying value of integer variable using pointer func updateValue(ptr *int, newValue int) { *ptr = newValue } func main() { value := 5 updateValue(&value, 10) // pass pointer to value fmt.Println(value) // 10 }
Returning multiple values from a function: Go allows returning multiple values from a function. This is useful in cases where a function needs to return both a value and an error (for example).
// simple example of using pointer to return multiple values from function func divide(numerator, denominator int) (int, error) { if denominator == 0 { return 0, fmt.Errorf("cannot divide by zero") } quotient := numerator / denominator remainder := numerator % denominator return quotient, &remainder } func main() { quotient, remainderPtr := divide(10, 3) fmt.Println(quotient, *remainderPtr) // 3 1 }
Advantages
The main advantage of using pointers over regular variables is that they provide a way to modify the original value of a variable even when it has gone out of scope. This is because the pointer holds the memory address of the variable, which can be accessed by another variable or function even after the original variable has gone out of scope.
This can be useful in cases where you need to modify the state of an object across multiple functions or methods. However, pointer usage can sometimes make code more complicated and harder to reason about, so should be used judiciously.
Conclusion
Overall, pointers are important for understanding many of the implementation details of Go's standard packages and functions, and for writing efficient and reliable Go code. By mastering this fundamental concept, developers can become proficient in working with Go.
If you find errors, blame ChatGPT. If you like this article give me a vote. I will write more as long as I can, to finish learning Go. You know I'm also learning. Right?
Have fun, learn and prosper ๐๐๐ผ