Golang methods: receivers, struct methods, and interfaces

Golang method and go methods: value vs pointer receivers, golang struct methods and calls, methods on defined types, method sets and interfaces; same-package rules and when Go adjusts & for you.

Published

Updated

Read time 4 min read

Reviewed byDeepak Prasad

Golang methods: receivers, struct methods, and interfaces

Searches for golang method, golang methods, go methods, methods in golang, methods golang, method in golang, go method, or method golang all refer to the same feature: a function with a receiver—the short declaration before the method name that ties the function to a type. Golang struct methods are the most common form (behavior on a struct), but Go also allows methods on any defined type in the same package. There are no classes; a struct plus methods is the usual way to group data and behavior. For data layout first, see structs.

Tested with Go 1.24 on Linux.


Method syntax: receiver and name

A method is declared like a function, with an extra receiver parameter in parentheses:

go
type User struct {
	Name string
}

// Value receiver: method operates on a copy of User
func (u User) Greet() string {
	return "Hello " + u.Name
}

// Pointer receiver: method can change fields on the original value
func (u *User) SetName(name string) {
	u.Name = name
}

Call with dot syntax on a value or pointer (u.Greet(), u.SetName(...)). If u is a User value, the compiler still lets you call SetName and passes &u for you when it can take the address (see the spec: Calls).


Value receiver vs pointer receiver

Value receiver (t T) Pointer receiver (t *T)
Mutates original fields No (copy) Yes
Copies struct Yes No
Typical use Small, read-only Mutations, larger structs, consistency

Rule of thumb: if any method on a type needs a pointer receiver, many teams use pointer receivers for all methods on that type so you do not mix styles and accidentally copy large values.

go
package main

import "fmt"

type Counter struct{ n int }

func (c Counter) Value() int { return c.n } // read-only on copy

func (c *Counter) Inc() { c.n++ } // mutates through pointer

func main() {
	var c Counter
	c.Inc()
	fmt.Println(c.Value())
}
text
1

golang struct methods and calls

Struct methods are ordinary methods whose receiver is the struct (by value or pointer). Callers use instance.Method() regardless of whether the method uses a value or pointer receiver, as long as the receiver value is addressable when a pointer is needed.

go
type Product struct {
	Name  string
	Price float64
}

func (p Product) Label() string {
	return fmt.Sprintf("%s — %.2f", p.Name, p.Price)
}

func main() {
	p := Product{Name: "Desk", Price: 129.99}
	fmt.Println(p.Label())
}

Methods on other defined types

The receiver’s base type must be declared in the same package as the method. You cannot attach methods to a type from another package or to a predeclared type such as int or string. Wrap them in a new type:

go
type Score int

func (s Score) Doubled() Score { return s * 2 }

Methods and interfaces (method sets)

An interface is satisfied implicitly when a type offers the right methods. What counts is the method set:

  • For type T, only methods with receiver T belong to T’s method set.
  • For type *T, methods with receiver T or *T belong to *T’s method set.

So if the interface requires a method that is only declared with a pointer receiver, a plain T value does not implement the interface:

go
type Widget struct{}

func (w *Widget) Activate() {}

type Activator interface {
	Activate()
}

func main() {
	var w Widget
	var _ Activator = &w // OK
	// var _ Activator = w // compile error: *Widget method missing for Widget
}
text
cannot use w (variable of struct type Widget) as Activator value in variable declaration: Widget does not implement Activator (method Activate has pointer receiver)

Use &value (or store *Widget from the start) when the interface expects pointer-receiver methods.


Nil receivers and consistency

A method can be invoked on a nil pointer if the method is written to tolerate nil (many types check if t == nil { return ... }). If the method dereferences fields without a guard, a nil receiver panics like any other nil dereference. Document or guard when nil is allowed.


Summary

A golang method is a function bound to a type through a receiver; go methods and methods in golang are the same language feature with different search wording. Value receivers copy the receiver and suit small, immutable reads; pointer receivers underpin golang struct methods that mutate state, avoid copies, and often match interface method sets. Interfaces care about exact method sets, so pointer-only methods mean callers pass pointers. Methods cannot be bolted onto foreign or built-in types—define a named type in your package instead.


References


Frequently Asked Questions

1. What is the difference between a golang method and a function?

A method has a receiver before the name: func (r T) Name(...). A plain function has no receiver. You call methods with value.method(); functions use funcname(args).

2. When should I use a pointer receiver in Go?

Use a pointer receiver when the method mutates the receiver, when the struct is large enough that copying hurts, or when you need to match a *T method set for an interface. Many teams default to pointer receivers on structs for consistency.

3. Why does my type not implement an interface when the method looks right?

The method set of T contains only value-receiver methods; the method set of *T contains both value- and pointer-receiver methods. A variable of type T does not satisfy an interface that only lists pointer-receiver methods unless you use &T.

4. Can I add methods to string or int?

Not directly. Define a new named type in your package (type MyString string) and attach methods to that. The base type must be declared in the same package as the method.
Antony Shikubu

Systems Integration Engineer

Highly skilled software developer with expertise in Python, Golang, and AWS cloud services.