Go supports methods defined on struct types. Methods are functions with a special receiver argument that appears between the func keyword and the method name.
package mainimport "fmt"type rect struct { width, height int}// This area method has a receiver type of *rect.func (r *rect) area() int { return r.width * r.height}// Methods can be defined for either pointer or value receiver types.// Here's an example of a value receiver.func (r rect) perim() int { return 2*r.width + 2*r.height}func main() { r := rect{width: 10, height: 5} // Call the methods defined for our struct. fmt.Println("area: ", r.area()) fmt.Println("perim:", r.perim()) // Go automatically handles conversion between values and pointers // for method calls. You may want to use a pointer receiver to avoid // copying on method calls or to allow the method to mutate the struct. rp := &r fmt.Println("area: ", rp.area()) fmt.Println("perim:", rp.perim())}
Go automatically handles conversions between values and pointers for method calls:
r := rect{width: 10, height: 5}rp := &r// All of these work:r.area() // Go converts to &r automaticallyrp.area() // Direct pointer callr.perim() // Direct value callrp.perim() // Go dereferences automatically
You don’t need to worry about whether you have a value or pointer when calling methods — Go handles the conversion for you.
Pointer receivers and value receivers have different method sets:
A value of type T can only call methods with value receivers
A value of type *T can call methods with both pointer and value receivers
This matters when implementing interfaces!
type Shaper interface { area() int}// If area() has a pointer receiver (*rect)func (r *rect) area() int { return r.width * r.height }// Then only *rect implements Shaper, not rectvar s Shaper = &rect{width: 10, height: 5} // ✓ Works// var s Shaper = rect{width: 10, height: 5} // ✗ Compile error