Summary: in this tutorial, you will learn about Go methods, which allow you to define methods on types including structs.
Go methods allow you to define functions on types including structs. By definition, Go methods are functions with a receiver argument.
Here’s the syntax for defining a method:
func (r receiverType) methodName(parameters) returnType {
// method body
}
Code language: Go (go)
In this syntax, you place the receiver argument between the func
keyword and method name. The rest is the same as the syntax for defining a function.
Go method example
Step 1. Define a Rectangle
struct that has length
and width
fields:
type Rectangle struct {
length float64
width float64
}
Code language: Go (go)
Step 2. Create a function that calculates the area of a Rectangle
struct:
func Area(r Rectangle) float64 {
return r.length * r.width
}
Code language: Go (go)
Step 3. Create a Rectangle
struct value, calculate the area, and display the result on the screen:
func main() {
r := Rectangle{length: 10, width: 5}
fmt.Println("Area of rectangle is", Area(r))
}
Code language: Go (go)
Here’s the complete program:
package main
import "fmt"
type Rectangle struct {
length float64
width float64
}
func Area(r Rectangle) float64 {
return r.length * r.width
}
func main() {
r := Rectangle{length: 10, width: 5}
fmt.Println("Area of rectangle is", Area(r))
}
Code language: Go (go)
Output:
Area of rectangle is 50
Code language: Go (go)
The program works fine. But it’s more intuitive if we can call the Area()
function like this:
r.Area()
Code language: Go (go)
To do this, we can define the Area()
function as a method of the Rectangle
struct type.
Step 4. Change the Area()
function to a method:
func (r Rectangle) Area() float64 {
return r.length * r.width
}
Code language: Go (go)
In this example:
- First, specify the receiver argument
(r Rectangle)
between thefunc
keyword andArea
method name. - Second, remove parameters from the
Area()
function because we can access thelength
andwidth
field via ther
parameter.
The Area()
function becomes a method of the Rectangle
struct type.
Here’s the updated program:
package main
import "fmt"
type Rectangle struct {
length float64
width float64
}
func (r Rectangle) Area() float64 {
return r.length * r.width
}
func main() {
r := Rectangle{length: 10, width: 5}
fmt.Println("Area of rectangle is", r.Area())
}
Code language: Go (go)
Define receivers as pointers
Like functions, methods use the pass-by-value mechanism. This means that methods copy arguments and work on the copied versions inside their body. Any changes methods make to the arguments will not be reflected in the original arguments.
Therefore, if you want to change the fields of a struct inside methods, you need to use a pointer to the struct as the receiver.
For example, the following defines the Scale()
method of the Rectangle
struct. It uses a pointer as a receiver:
func (r *Rectangle) Scale(factor float64) {
r.length *= factor
r.width *= factor
}
Code language: Go (go)
In this example, the Scale
method changes both the length
and width
fields of the rectangle. You may wonder why we can access them using this syntax:
r.length
r.width
Code language: Go (go)
But not using the correct syntax:
(*r).length
(*r).width
Code language: Go (go)
This is possible due to the automatic dereferencing feature in GO.
Go allows you to access struct fields through a pointer without explicitly dereferencing the pointer.
When the Go compiler compiles the code, it will automatically convert r.width
to (*r).width
for you, making the syntax more convenient and easier to read.
Here’s the updated program that includes the Scale()
method:
package main
import "fmt"
type Rectangle struct {
length float64
width float64
}
func (r Rectangle) Area() float64 {
return r.length * r.width
}
func (r *Rectangle) Scale(factor float64) {
r.length *= factor
r.width *= factor
}
func main() {
r := Rectangle{length: 10, width: 5}
r.Scale(10)
fmt.Println(r)
}
Code language: Go (go)
Output:
{100 50}
Summary
- Methods are functions with a receiver argument.
- Use a pointer to the struct as a receiver to modify the struct fields inside methods.