Golang Methods Tutorial [Practical Examples]

Tech reviewed: Deepak Prasad
Golang Methods Tutorial [Practical Examples]

Quick Cheat Sheet: Golang Methods

Method Syntax (Receiver + Function)

go
// Basic method syntax
type User struct {
    Name string
}

// Method with value receiver
func (u User) getName() string {
    return u.Name
}

// Method with pointer receiver
func (u *User) setName(name string) {
    u.Name = name
}
  • Methods = functions with a receiver
  • Receiver defines which type the method belongs to
  • Can be struct or custom type

Value vs Pointer Receiver (When to Use What)

go
// Value receiver (copy)
func (u User) display() string {
    return u.Name
}

// Pointer receiver (modify original)
func (u *User) update(name string) {
    u.Name = name
}
Feature Value Receiver Pointer Receiver
Modifies data ❌ No ✅ Yes
Performance Copies data Uses reference
Use case Read-only Update struct
Recommended for Small structs Large structs

Use pointer receiver if you want to modify data or avoid copying


What are Methods in Golang?

Methods in Go are functions that are attached to a type using a receiver.

go
type User struct {
    Name string
}

func (u User) greet() string {
    return "Hello " + u.Name
}
go
u := User{Name: "John"}
fmt.Println(u.greet())
  • Methods allow you to define behavior on types
  • Used for struct, custom types, and interfaces
  • Core building block for Go’s object-oriented style

Methods vs Functions (Key Difference)

go
// Function
func greet(u User) string {
    return "Hello " + u.Name
}

// Method
func (u User) greet() string {
    return "Hello " + u.Name
}
Feature Function Method
Attached to None Type (receiver)
Call style greet(u) u.greet()
Use case General logic Type-specific logic

Use methods when logic belongs to a specific type

Why Go Uses Receivers Instead of Classes

Unlike languages like Java or Python:

  • Go does NOT have classes
  • Uses struct + methods instead
go
type User struct {
    Name string
}

func (u User) greet() string {
    return "Hello " + u.Name
}

This gives:

  • Simpler design
  • Better readability
  • More flexibility (methods on any type)

Think of struct + methods = lightweight class


Method Receivers in Go (Core Concept)

Value Receiver (Copy Behavior)

go
type User struct {
    Name string
}

// Value receiver (copy)
func (u User) display() string {
    return u.Name
}

func main() {
    u := User{Name: "John"}
    fmt.Println(u.display())
}
  • Works on a copy of the struct
  • Changes inside method do NOT affect original value
  • Good for read-only operations

Use value receiver when data does not need modification

Pointer Receiver (Modify Original Value)

go
type User struct {
    Name string
}

// Pointer receiver (modifies original)
func (u *User) updateName(name string) {
    u.Name = name
}

func main() {
    u := User{Name: "John"}
    u.updateName("Alice")
    fmt.Println(u.Name)
}
  • Works on the original struct
  • Allows modification of fields
  • Avoids copying large structs

Use pointer receiver for updates and better performance


Methods on Structs (Most Common Use Case)

Define Method on Struct

go
type Product struct {
    Name  string
    Price float64
}

func (p Product) details() string {
    return fmt.Sprintf("%s costs %.2f", p.Name, p.Price)
}
  • Struct methods define behavior for data types
  • Most common use case in Go

Call Method on Struct Instance

go
p := Product{Name: "Laptop", Price: 75000}
fmt.Println(p.details())
  • Use dot notation → instance.method()
  • Looks similar to OOP languages

Methods on Non-Struct Types

Custom Type Methods (type MyInt int)

go
type MyInt int

func (n MyInt) square() MyInt {
    return n * n
}

func main() {
    var x MyInt = 5
    fmt.Println(x.square())
}
  • Methods can be defined on custom types
  • Not limited to structs

Limitations (Same Package Rule)

go
// ❌ Not allowed
func (s string) myMethod() {}
  • You cannot define methods on:
    • Built-in types (like int, string)
    • Types from another package

Create a custom type if you want to add methods


Methods with Interfaces (Real Usage)

How Methods Define Interfaces

In Go, interfaces are defined by the methods they declare. Any type that implements those methods automatically satisfies the interface.

go
type Greeter interface {
    greet() string
}

type User struct {
    Name string
}

func (u User) greet() string {
    return "Hello " + u.Name
}
  • Interfaces define behavior, not data
  • Any type with matching methods automatically implements the interface
  • No explicit implements keyword required

Interfaces in Go are satisfied implicitly

Implement Interface Using Methods

go
func sayHello(g Greeter) {
    fmt.Println(g.greet())
}

func main() {
    u := User{Name: "John"}
    sayHello(u)
}
  • The User struct implements Greeter
  • Method greet() satisfies the interface
  • Enables flexible and reusable code

Interfaces help decouple logic and improve testability


Common Errors and Best Practices

Method not found error (wrong receiver)

go
type User struct {
    Name string
}

func (u *User) update() {}

func main() {
    u := User{Name: "John"}
    u.update() // works due to automatic address conversion
}
  • Go auto-handles pointer/value in many cases
  • But mismatch can cause confusion in interfaces

Fix: Ensure correct receiver type when implementing interfaces

Pointer vs value confusion

go
type User struct {
    Name string
}

func (u *User) update() {}

type Updater interface {
    update()
}

func main() {
    var u User
    var up Updater = u // ❌ error
}

Error occurs because:

  • Interface expects pointer receiver
  • Value type does not satisfy it

Fix:

go
var up Updater = &u

Interfaces must match receiver type exactly

When to use pointer receiver (rule of thumb)

Use pointer receiver when:

  • You want to modify struct fields
  • Struct is large (performance)
  • Method must satisfy interface with pointer receiver

Use value receiver when:

  • Data is small
  • Method is read-only
go
// Rule of thumb
Small + read-only  value receiver  
Large or mutable  pointer receiver

[[FAQ]]


Summary

  • Methods in Go are functions with receivers
  • Value receivers work on copies, pointer receivers modify original data
  • Interfaces are implemented implicitly via methods
  • Receiver type must match when using interfaces
  • Prefer pointer receivers for performance and consistency

Rule of thumb:

  • Struct behavior → methods
  • Abstraction → interfaces

Official Documentation

Antony Shikubu

Systems Integration Engineer

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

  • Mastering Ansible Automation
  • Docker and Kubernetes: The Complete Guide
  • Go: Data Structures, Algorithms and Design Patterns With Go
  • Go (programming language)
  • Python (programming language)
  • Amazon Web Services