Methods
What is a method?
Section titled “What is a method?”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().
Value receivers vs pointer receivers
Section titled “Value receivers vs pointer receivers”The receiver can be either a value or a pointer:
func (c Counter) Value() int { return c.count } // value receiverfunc (c *Counter) Inc() { c.count++ } // pointer receiverValue receiver (t T) | Pointer receiver (t *T) | |
|---|---|---|
| Sees | A copy of the value | The original value |
| Can mutate? | No — mutates the copy only | Yes |
| Callable on | Both T and *T | Both T (addressable) and *T |
| Use when | Read-only; small, cheap to copy | Mutation; 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 on any named type
Section titled “Methods on any named type”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.
Method sets
Section titled “Method sets”The method set of a type determines which interfaces it satisfies:
- The method set of
Tcontains all methods with value receiver(t T). - The method set of
*Tcontains 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 structfunc (c *Counter) Inc() { c.count++}
// Value receiver — read-onlyfunc (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())}Loading Go runtime (first run only, ~8 MB)…