Pointers

Here we talk about the usage of Pointers in Golang. We don't discuss pointer theories.

A pointer stores the memory address of another variable.

x := 5 // value of x is 5
y := x // value of y is 5
z := &x // value of z is the memory address of x

*z = 6 // value of x is updated to 6
fmt.Println(*z) // prints 6
  • * is called the dereference operator

Syntax to define a pointer: var p *int // p is an integer type pointer

The & operator generates a pointer to its operand.

greeting := "yellow"
ptr := &greeting // a pointer to greeting variable

Why use Pointers

  • To pass the value by reference
  • Increase the performance and memory efficiency.
func replaceMsg(msg *string) {
    val := *msg
    val = strings.ReplaceAll(val, "Hi", "Hello")
    *msg = val
}
func main() {
    m := "Hi, Bella. Hi, Edward. Hope you're doing well!"
    replaceMsg(&m)
    fmt.Println(m)
}

Let's go through the above function code lines.

  • The val := *msg dereferences the pointer msg to get its actual string value. Then it is assigned to the val variable.
  • val = strings.ReplaceAll(val, "Hi", "Hello"): replaces all occurrences of "Hi" with "Hello" in val
  • *msg = val: writes the modified string to the memory location msg points to.

Nil Pointers

If a pointer points to nothing, the code panics. Therefore, you should always check whether a pointer is nil before you move further in your code.

The updated replaceMsg() with the safety check for a nil pointer is given below.

func replaceMsg(msg *string) {
    if msg == nil { // nil pointer check
        return
    }
    val := *msg
    val = strings.ReplaceAll(val, "Hi", "Hello")
    *msg = val
}

Pointer receivers

Methods can take pointers as the receiver type. Those methods can directly modify the values the pointer points to.

type car struct {
    color string
}

func (c *car) setColor(color string) {
   c.color = color 
}
func main() {
    c := car {
        color: "green"
    }
    c.setColor("purple")
    fmt.Println(c.color) // prints "purple"
}