BudiBadu Logo

Samplebadu

Code with Example
BudiBadu Logo
Samplebadu

Go by Example: Methods

Go 1.23

Learn how to define methods on types in Go, a key aspect of its object-oriented capabilities. This example distinguishes between value receivers and pointer receivers, explaining when to use each for efficiency and state modification.

Code

package main

import "fmt"

type rect struct {
    width, height int
}

// Method with pointer receiver
func (r *rect) area() int {
    return r.width * r.height
}

// Method with value receiver
func (r rect) perim() int {
    return 2*r.width + 2*r.height
}

// Method that modifies the receiver
func (r *rect) scale(f int) {
    r.width = r.width * f
    r.height = r.height * f
}

func main() {
    r := rect{width: 10, height: 5}

    // Call methods
    fmt.Println("area: ", r.area())
    fmt.Println("perim:", r.perim())

    // Go handles conversion between values and pointers
    rp := &r
    fmt.Println("area: ", rp.area())
    fmt.Println("perim:", rp.perim())
    
    // Modifying method
    r.scale(2)
    fmt.Println("scaled area:", r.area())
}

Explanation

Go supports methods defined on struct types, providing object-oriented programming capabilities without classes. Methods are functions with a special receiver argument that appears between the func keyword and the method name. This receiver binds the function to the type, allowing you to call the method using dot notation on instances of that type.

The choice between pointer receivers (*Type) and value receivers (Type) is critical for both performance and correctness. Use pointer receivers when you need to modify the receiver's state (like the scale method) or when the struct is large enough that copying it would be expensive. Value receivers create a copy of the struct, so modifications inside the method don't affect the original. For consistency, if any method needs a pointer receiver, it's idiomatic to use pointer receivers for all methods on that type.

Go provides convenient automatic dereferencing and address-taking for method calls. You can call a pointer receiver method on a value—Go automatically takes its address (&value). Conversely, you can call a value receiver method on a pointer—Go automatically dereferences it (*pointer). This syntactic sugar reduces boilerplate while maintaining type safety, making method calls feel natural regardless of whether you're working with a value or pointer.

Code Breakdown

10-12
Defining a method "area" with a pointer receiver (*rect). This allows the method to access the struct without copying it. It's generally good practice to use pointer receivers for consistency.
15-17
Defining a method "perim" with a value receiver (rect). This receives a copy of the struct. Changes made to "r" inside this method would not affect the original struct.
20-23
A method that modifies the struct must use a pointer receiver. "scale" multiplies the width and height, updating the original struct.
32-35
Go automatically handles the indirection. We can call pointer methods on values (r.area()) and value methods on pointers (rp.perim()) seamlessly.