Skip to content

Methods

A method is a function with a receiver — an extra parameter that appears between the func keyword and the function name. The receiver binds the function to a named type.

func (r Rectangle) Area() float64 {
return r.Width * r.Height
}

Here r Rectangle is the receiver. Area is now a method of Rectangle, callable as rect.Area().

The receiver can be either a value or a pointer:

func (c Counter) Value() int { return c.count } // value receiver
func (c *Counter) Inc() { c.count++ } // pointer receiver
Value receiver (t T)Pointer receiver (t *T)
SeesA copy of the valueThe original value
Can mutate?No — mutates the copy onlyYes
Callable onBoth T and *TBoth T (addressable) and *T
Use whenRead-only; small, cheap to copyMutation; large struct; consistent method set

Be consistent: if any method on a type needs a pointer receiver, give all methods of that type pointer receivers. Mixing causes subtle method-set issues when the type is used as an interface value.

Methods are not limited to structs. You can define methods on any named type in your package:

type Celsius float64
func (t Celsius) String() string {
return fmt.Sprintf("%.1f°C", float64(t))
}

You cannot define a method on a type from another package (e.g., func (s string) Upper() is illegal), but wrapping it in a local named type is always allowed.

The method set of a type determines which interfaces it satisfies:

  • The method set of T contains all methods with value receiver (t T).
  • The method set of *T contains all methods — both (t T) and (t *T).

This is why an interface requiring a pointer-receiver method can only be satisfied by *T, not by T.

package main
import "fmt"
type Counter struct {
count int
}
// Pointer receiver — mutates the struct
func (c *Counter) Inc() {
c.count++
}
// Value receiver — read-only
func (c Counter) Value() int {
return c.count
}
type Celsius float64
func (t Celsius) String() string {
return fmt.Sprintf("%.1f\u00b0C", float64(t))
}
func main() {
c := Counter{}
c.Inc()
c.Inc()
c.Inc()
fmt.Println(c.Value())
temp := Celsius(36.6)
fmt.Println(temp.String())
}
A method with a value receiver `(c Counter)` modifies `c.count`. What happens to the original variable?
Which type's method set includes both value-receiver and pointer-receiver methods?
You want to define a method on `type Kelvin float64`. What is the constraint?
Your type has five methods. Four use value receivers and one uses a pointer receiver. What should you do?