People comparing golang function vs method, golang method vs function, go method vs function, function vs method, golang methods vs functions, or go function vs method are usually asking two things: how declaration syntax differs (receiver or not), and how to choose for readability and mutability. In Go there is only one keyword for both: func. A package-level function has no receiver; a method golang style API attaches the function to a type via a receiver before the method name. This page contrasts both with small triangle examples and points to deeper guides on functions and methods.
Tested with Go 1.24 on Linux.
Golang function declaration syntax (no receiver)
A plain function lives at package scope (or inside another function as a literal). Golang function declaration syntax is:
func Name(parameters) optionalResults { body }Example: build a full name from two strings—no os.Args required.
package main
import "fmt"
func FullName(first, last string) string {
return fmt.Sprintf("%s %s", first, last)
}
func main() {
fmt.Println(FullName("John", "Doe"))
}Running the program prints John Doe.
You call it as FullName("John", "Doe"): the type does not appear before the name.
Method in Go: receiver before the name
A method is a function with a receiver in its own parameter list between func and the method name:
func (receiver Type) MethodName(parameters) optionalResults { body }The receiver is often a struct or pointer to struct. See Golang methods for value vs pointer receivers and naming conventions.
package main
import "fmt"
type Triangle struct {
base, height float64
}
func (t Triangle) Area() float64 {
return 0.5 * t.base * t.height
}
func main() {
t := Triangle{base: 3, height: 4}
fmt.Println(t.Area())
}This prints 6. The call form is t.Area(): the value t is the receiver.
Same logic as a function taking *Triangle
You can express the same math as a package function that takes the struct (or pointer) as an ordinary parameter:
package main
import "fmt"
type Triangle struct {
base, height float64
}
func AreaOf(t *Triangle) float64 {
return 0.5 * t.base * t.height
}
func main() {
t := &Triangle{base: 3, height: 4}
fmt.Println(AreaOf(t))
}Both versions print 6. Choosing function vs method is mostly API design: AreaOf(t) reads like a procedure on data; t.Area() reads like a capability of Triangle.
Golang methods vs functions: practical guidance
- Use a method when the first argument is always a specific type you control and callers will think in terms of that type (
db.Save(),req.Validate()). - Use a function when the operation is naturally stateless over its parameters, or you want to avoid tying the API to one concrete struct.
- Use a pointer receiver
*Twhen the method must mutate the receiver orTis large; use a value receiverTfor small immutable value types.
Go is not class-based OOP, but methods still help you group behavior next to data without inventing artificial “service” structs.
Summary
Golang function vs method comes down to the receiver: same func keyword, but methods declare (r Type) before the name and are invoked with value.Method(). Golang function declaration syntax never includes that receiver clause. For go methods vs functions at call sites, prefer methods when the operation belongs to one type’s API; prefer functions for generic utilities. Combine this page with functions and methods for syntax, parameters, and receiver rules end to end.
References
Frequently Asked Questions
1. What is the golang function vs method difference?
func Name(params) results; a method adds a receiver before the name, func (r Type) Name(params) results, and is called on a value of that type with v.Name().2. What does golang function declaration syntax look like?
func followed by the name, parameter list in parentheses, optional result list, then a block—there is no receiver: func Add(a, b int) int { return a + b }.3. When should I use golang methods vs functions?
area := t.Area()); prefer a function when the logic is a pure transformation of its parameters (Area(t *Triangle)).4. What is a pointer receiver vs value receiver?
func (t T) M() copies T for the call; a pointer receiver func (t *T) M() can mutate T and avoids copying large structs; see the golang-methods guide on the site for naming and pointer/value rules.
