What is a method?
A method is a function with a special receiver argument that appears between the func keyword and the method name. The receiver binds the function to a named type, letting you call it with dot syntax like value.Method().
package main
import "fmt"
type Rectangle struct {
Width, Height float64
}
// Area has a value receiver (r Rectangle).
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func main() {
r := Rectangle{Width: 3, Height: 4}
fmt.Println(r.Area()) // 12
}Value vs pointer receivers
A value receiver (r Rectangle) operates on a copy, so changes do not affect the original. A pointer receiver (r *Rectangle) operates on the original, so it can mutate the receiver's fields. Use a pointer receiver when the method must modify state or when copying a large struct would be wasteful.
type Counter struct{ n int }
// Pointer receiver: mutates the original.
func (c *Counter) Inc() {
c.n++
}
func main() {
c := Counter{}
c.Inc() // Go automatically takes &c
fmt.Println(c.n) // 1
}Method sets
The method set of type T contains methods declared with value receivers. The method set of *T contains methods with both value and pointer receivers. This matters for interface satisfaction: only *T satisfies an interface whose implementation uses a pointer receiver.
Methods can be declared on any named type in the same package, not just structs (e.g. type MyInt int).
You cannot declare methods on types from other packages or on built-in types like int directly.
Go auto-addresses/dereferences: for an addressable value v, v.PtrMethod() is shorthand for (&v).PtrMethod().
Be consistent: if any method needs a pointer receiver, give all of that type's methods pointer receivers.
type Celsius float64
func (c Celsius) ToF() float64 {
return float64(c)*9/5 + 32
}
func main() {
c := Celsius(100)
fmt.Println(c.ToF()) // 212
}