Classes → Structs
Defining data types and behavior
Introduction
In this lesson, you'll learn about classes → structs in Go. Coming from Python, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In Python, you're familiar with defining data types and behavior.
Go has its own approach to defining data types and behavior, which we'll explore step by step.
The Go Way
Let's see how Go handles this concept. Here's a typical example:
package main
type Person struct {
Name string
Age int
}
func (p Person) Greet() string {
return "Hi, I'm " + p.Name
}
func (p *Person) Birthday() {
p.Age++
}
// No inheritance — use embedding
type Employee struct {
Person // embedded: Employee has Name, Age, Greet()
Department string
}
e := Employee{
Person: Person{"Alice", 30},
Department: "Engineering",
}
fmt.Println(e.Greet()) // inherited from PersonComparing to Python
Here's how you might have written similar code in Python:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
def greet(self) -> str:
return f"Hi, I'm {self.name}"
def birthday(self) -> None:
self.age += 1
class Employee(Person):
department: str
def __init__(self, name, age, dept):
super().__init__(name, age)
self.department = deptYou may be used to different syntax or behavior.
Go has no classes — structs + methods
You may be used to different syntax or behavior.
Go has no inheritance — use struct embedding (composition)
You may be used to different syntax or behavior.
Go pointer receiver (*Person) for mutation; Python mutates via self
You may be used to different syntax or behavior.
@dataclass auto-generates __init__; Go uses struct literals
Step-by-Step Breakdown
1. Structs vs Classes
Go structs hold data; methods are separate functions with a receiver. Python classes bundle data and methods together.
class Person:
def __init__(self, name, age): ...
def greet(self): ...type Person struct { Name string; Age int }
func (p Person) Greet() string { ... }2. Pointer Receiver
To modify struct fields in a method, use a pointer receiver (*Person). Python's self always allows mutation.
def birthday(self): self.age += 1func (p *Person) Birthday() { p.Age++ }3. Embedding vs Inheritance
Go has no inheritance. Embed a struct to reuse its fields and methods — the embedded type's methods are promoted.
class Employee(Person): pass # inheritstype Employee struct {
Person // promoted — e.Greet() works
Department string
}Common Mistakes
When coming from Python, developers often make these mistakes:
- Go has no classes — structs + methods
- Go has no inheritance — use struct embedding (composition)
- Go pointer receiver (*Person) for mutation; Python mutates via self
Key Takeaways
- Python class → Go struct + receiver methods
- Python self mutates → Go needs *pointer receiver
- Inheritance → struct embedding (composition)
- @dataclass → struct literal initialization