Method Receiver and Pointer in Golang

When a method is called, the structure object for which the method is defined is passed to it by value. What does that mean? Consider the following example:

package main

import "fmt"

type book struct {
	title      string
	pageNumber int
}

func (b book) changeTitle(newTitle string) {
	b.title = newTitle
}

func main() {

	var postgres = book{title: "Learn Postgres", pageNumber: 400}
	fmt.Println("title before change : ", postgres.title)
	postgres.changeTitle("Learn Docker and Kubernetes")
	fmt.Println("title after the change : ", postgres.title)
}

The book structure has an changeTitle method that accepts the newTitle parameter and changes the value of the title field on the structure. That is, when you call With this method, we expect the title of the book to change. However, the console output shows us that the value of the age field does not change:

title before change :  Learn Postgres
title after the change :  Learn Postgres

Using Pointers for State Modification

Because when the changeTitle method is called, it gets a copy of the tom structure. That is, the postgres structure is copied to another memory location, and then the changeTitle method works with the copy without affecting the original postgres structure in any way.

However, this behavior may not be desirable. What if we want to change the state of the structure in this way? In this case, you need to use pointers to the structs:

package main

import "fmt"

type book struct {
	title      string
	pageNumber int
}

func (b *book) changeTitle(newTitle string) {
	(*b).title = newTitle
}

func main() {

	var postgres = book{title: "Learn Postgres", pageNumber: 400}
	var pp *book = &postgres
	fmt.Println("title before change : ", postgres.title)
	pp.changeTitle("Learn Docker and Kubernetes")
	fmt.Println("title after the change : ", postgres.title)
}

The changeTitle method now takes a pointer to the book structure: *(b *book)*, which is the address of the structure in memory. Using the dereferencing operation, we get the value at this address in memory and change the age field:

(*b).title = newTitle

In the main function, define a pointer to the book structure and pass it the address of the tom structure:

var pp *book = &postgres

Then we call the updateAge method:

pp.changeTitle("Learn Docker and Kubernetes")

Thus, the changeTitle method will get the address that is stored in pp (postgres pointer) and use this address to access the postgres structure by changing the value of its title property.

Now if we run this code will get the result that we need:

title before change :  Learn Postgres
title after the change :  Learn Docker and Kubernetes

Note: that even though the changeTitle method is defined for a pointer to the book structure, we can still call this method for the book object as well:

func main() {

	var postgres = book{title: "Learn Postgres", pageNumber: 400}

	fmt.Println("title before change : ", postgres.title)
	postgres.changeTitle("Learn Docker and Kubernetes")

	fmt.Println("title after the change : ", postgres.title)
}