Globant
Published in

Globant

GO: Method Receiver - Pointer v/s Value

If you are new to Go, then you must have come across the concept of Methods and Functions. Let's find the difference between two-

A function is declared by specifying the types of the arguments, the return values, and the function body.

type Person struct {
Name string
Age int
}
func NewPerson(name string, age int) *Person {
return &Person{
Name: name,
Age: age,
}
}

A method is just a function with a receiver argument. It is declared with the same syntax with the addition of the receiver.

func (p *Person) isAdult bool {
return p.Age > 18
}

In the above method declarations, we declared the isAdult method on the *Person type.

Now we will see the difference between the value receiver and Pointer receiver.

Value receiver makes a copy of the type and pass it to the function. The function stack now holds an equal object but at a different location on memory. That means any changes done on the passed object will remain local to the method. The original object will remain unchanged.

Pointer receiver passes the address of a type to the function. The function stack has a reference to the original object. So any modifications on the passed object will modify the original object.

Let’s understand this with the example-

package mainimport (
"fmt"
)
type Person struct {
Name string
Age int
}
func ValueReceiver(p Person) {
p.Name = "John"
fmt.Println("Inside ValueReceiver : ", p.Name)
}
func PointerReceiver(p *Person) {
p.Age = 24
fmt.Println("Inside PointerReceiver model: ", p.Age)
}
func main() {
p := Person{"Tom", 28}
p1:= &Person{"Patric", 68}
ValueReceiver(p)
fmt.Println("Inside Main after value receiver : ", p.Name)
PointerReceiver(p1)
fmt.Println("Inside Main after value receiver : ", p1.Age)
}
O/P-
Inside ValueReceiver : John
Inside Main after value receiver : Tom
Inside PointerReceiver : 24
Inside Main after pointer receiver : 24

This shows that the method with value receivers modifies a copy of an object, And the original object remains unchanged. Like- Name of a person changed from Tom to John by ValueReceiver method, but this change was not reflected in the main method. On the other hand, the method with pointer receivers modifies the actual object. Like- Age of a person changed from 68 to 24 by the PointerReceiver method, and the same changes reflected in the main method. You can check the fact by printing out the address of the object before and after manipulation by pointer or value receiver.

So how to choose between Pointer vs Value receiver?

If you want to change the state of the receiver in a method, manipulating the value of it, use a pointer receiver. It’s not possible with a value receiver, which copies by value. Any modification to a value receiver is local to that copy. If you don’t need to manipulate the receiver value, use a value receiver.

The Pointer receiver avoids copying the value on each method call. This can be more efficient if the receiver is a large struct,

Value receivers are concurrency safe, while pointer receivers are not concurrency safe. Hence a programmer needs to take care of it.

Notes-

  1. Try to use the same receiver type for all your methods as much as possible.
  2. If state modification needed, use pointer receiver if not use value receiver.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store