Why you should avoid pointers in Golang

Daryl Ng
3 min readApr 5, 2023

Go is a modern programming language that has gained popularity due to its simplicity, readability, and efficient memory management. One of the key features of Go is its ability to handle memory automatically through garbage collection. However, Go also supports pointers, which can be a powerful tool in certain cases. But sometimes, using pointers can lead to errors and cause problems, making it necessary to avoid them. In this article, we will discuss some ways to avoid using pointers in Go.

Use value types instead of pointers

Go has two types of data types: value types and reference types. Value types include basic data types like integers, floats, and strings, and they are passed by value when they are used in functions. Reference types, on the other hand, include slices, maps, channels, and pointers, and they are passed by reference. It’s often better to use value types instead of reference types to avoid using pointers.

For example, if you need to pass a slice to a function, you can pass it as a value instead of a pointer:

func doSomething(slice []int) {
// do something with the slice
}
func main() {
mySlice := []int{1, 2, 3}
doSomething(mySlice)
}

Here, mySlice is passed as a value to doSomething, and any changes made to the slice inside the function are local and don't affect the original slice.

Use interfaces instead of pointers

Go supports interfaces, which are a way to define behavior without specifying the implementation. By using interfaces, we can avoid using pointers and still achieve polymorphism.

For example, instead of using a pointer to a struct, we can define an interface that the struct implements:

type Animal interface {
Speak() string
}
type Dog struct {}

func (d Dog) Speak() string {
return "Woof!"
}

func main() {
var animal Animal
animal = Dog{}
fmt.Println(animal.Speak()) // Output: Woof!
}

Here, we define an Animal interface that has a Speak method. The Dog struct implements the Animal interface, and we can use polymorphism to call the Speak method without using a pointer to the Dog struct.

Use channels instead of pointers for communication

Go supports channels, which are a way to communicate between concurrent processes without using locks or mutexes. By using channels, we can avoid using pointers and still achieve safe communication.

For example, instead of using a pointer to a variable, we can pass the variable through a channel:

func doSomething(input <-chan int, output chan<- int) {
// read from input channel
// do something with the value
// write to output channel
}
func main() {
input := make(chan int)
output := make(chan int)
go doSomething(input, output)
input <- 42
result := <-output
}

Here, we define a doSomething function that reads from an input channel, processes the value, and writes to an output channel. Instead of using pointers to pass the values, we use channels to communicate between the functions.

In conclusion, using pointers can be a powerful tool in Go, but it’s not always necessary or recommended. By using value types, interfaces, and channels, we can avoid using pointers and still achieve safe and efficient programming. Avoiding pointers can lead to simpler and more readable code, and reduce the chances of errors and memory leaks.

--

--