Should I use a pointer or a value receiver? A single type should either use pointer or value receivers for all its methods. It’s a matter of consistency and safeness.

When you need to write a method that modifies a type, you have two solutions. You could either change the type instance in place or return a new modified version of it.

If you decide to modify in place, you will need a pointer receiver and create a mutable type that is not thread-safe.

If you decide to return a modified version, you will need a value receiver and create an immutable type that is thread-safe.

package main

import (
    "fmt"
)

type Mutable struct {
    i int
}

func (m *Mutable) Modify(n int) {
    m.i = n
}

type Immutable struct {
    i int
}

func (i Immutable) TryToModify(n int) {
    i.i = n
}

func (i Immutable) Modify(n int) Immutable {
    i.i = n
    return i
}

func main() {
    m := Mutable{1}
    m.Modify(2)
    fmt.Println(m)
    
    i := Immutable{1}
    i.TryToModify(2)
    fmt.Println(i)
    i = i.Modify(3)
    fmt.Println(i)
}
Go Playground