Defining Structs
Structs are Go's way to create custom types. They group related data together — like a class in other languages, but without inheritance. Go favors composition over inheritance.
type User struct {
Name string
Email string
Age int
}
// Create instances
u1 := User{Name: "Alice", Email: "[email protected]", Age: 30}
u2 := User{"Bob", "[email protected]", 25} // positional (fragile, avoid)
var u3 User // zero value: {"", "", 0}
fmt.Println(u1.Name) // Alice
u1.Age = 31 // modify field
fmt.Println(u1)
Alice
{Alice [email protected] 31}Methods — Value vs Pointer Receivers
Methods are functions attached to a type. The receiver determines whether the method gets a copy (value receiver) or a reference (pointer receiver):
type Rect struct {
Width, Height float64
}
// Value receiver: gets a COPY, can't modify original
func (r Rect) Area() float64 {
return r.Width * r.Height
}
// Pointer receiver: gets a REFERENCE, can modify original
func (r *Rect) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
func (r Rect) String() string {
return fmt.Sprintf("Rect(%.0fx%.0f)", r.Width, r.Height)
}
r := Rect{10, 5}
fmt.Println(r.Area()) // 50
r.Scale(2)
fmt.Println(r) // Rect(20x10)
fmt.Println(r.Area()) // 200
50 Rect(20x10) 200
| Receiver | Syntax | When to Use |
|---|---|---|
Value (r Rect) | Gets a copy | Read-only methods, small structs |
Pointer (r *Rect) | Gets a reference | Methods that modify, large structs |
Embedding (Composition)
Go doesn't have inheritance. Instead, you embed one struct inside another. The embedded struct's fields and methods are promoted to the outer struct:
type Address struct {
Street, City, Country string
}
type Employee struct {
Name string
Address // Embedded (no field name = promoted)
Salary float64
}
e := Employee{
Name: "Alice",
Address: Address{Street: "123 Main St", City: "NYC", Country: "US"},
Salary: 95000,
}
// Access promoted fields directly
fmt.Println(e.City) // NYC (promoted from Address)
fmt.Println(e.Address) // {123 Main St NYC US}
Composition over Inheritance
Go deliberately omits inheritance. Instead of "Employee IS A Person", Go says "Employee HAS A Address". This avoids the fragile base class problem and deep inheritance hierarchies. Embed what you need, compose behavior with interfaces.
Gets a copy, can't modify
Gets pointer, can modify
Use pointer if method mutates
Practice Exercises
Easy Hello World Variant
Modify the example to accept user input and print a personalized greeting.
Easy Code Reading
Read through the code examples above and predict the output before running them.
Medium Extend the Example
Take one code example and add error handling, input validation, or a new feature.