ProgrammingBackend Developer

Describe the features of working with pointers in Go: when to use them, how they differ from references in other languages, and what typical pitfalls are associated with their use?

Pass interviews with Hintsage AI assistant

Answer.

In Go, a pointer is a variable that stores the address of another variable. Unlike some languages, pointer arithmetic is not allowed in Go, making them safer. Pointers in Go are often used for:

  • Passing large structures to functions (to avoid copying).
  • Modifying an object from an external function.
  • Implementing complex data structures (e.g., lists, trees).

Go does not have explicit support for reference types, like C++, but slices and maps are already reference types by their nature and are often passed by value.

Example of passing a pointer and a value:

package main import "fmt" type User struct { Name string } func changeNameByValue(u User) { u.Name = "Vasya" } func changeNameByPointer(u *User) { u.Name = "Petya" } func main() { user := User{Name: "Ivan"} changeNameByValue(user) fmt.Println(user.Name) // Ivan changeNameByPointer(&user) fmt.Println(user.Name) // Petya }

Trick question.

Can pointers point to constants or literals in Go?

Correct answer: No, in Go, you cannot take the address of a constant or literal directly. You can only take the address of a variable:

x := 5 p := &x // OK p2 := &10 // Compilation error

This is often confused with languages where such behavior is allowed.

Examples of real errors due to lack of knowledge about the subtleties of the topic.


Story

In one project, a developer tried to pass a reference to an element of a slice, thinking they could safely modify the slice through a pointer. However, they were mistaken: a slice itself contains a pointer, but after append(), the address of the underlying array changes, and changes do not always reflect on the original data. This led to hard-to-trace bugs (data was "lost").


Story

A list of pointers to local variables was created in a loop, and after exiting the loop, all pointers pointed to the same variable (the iterated loop variable). The mistake was only noticed after a crash in production.


Story

The developer mistakenly believed that assigning a pointer frees the previous object from memory and explicitly assigned nil to the pointer, expecting immediate GC. In practice, in Go, the garbage collector decides when to clean objects, ignoring premature nullification of references. This led to memory leaks where timely memory release was expected.