💡 Key Mental Shifts

1. 🧱 Think in structs + functions, not classes

You’ll often define a struct for data and implement behavior through receiver methods.

    type User struct {
      Name string
    }

    func (u *User) Greet() string {
      return "Hello, " + u.Name
    }

2. 🧩 Use composition, not inheritance

Embed structs to reuse fields and methods:

    type Logger struct { ... }
    
    type Service struct {
      Logger // embedded struct
    }

3. 📝 Interfaces are contracts, not hierarchies

Declare small interfaces close to where they’re used. Avoid large “god interfaces” — Go prefers small, focused ones like:

    type Reader interface {
      Read(p []byte) (n int, err error)
    }

4. 🧠 No hidden magic — Go favors explicit behavior

What you see is what happens. Frameworks won’t inject behavior behind the scenes.

5. 🪓 Error handling is explicit

You’ll write more checks, but code becomes predictable and clear.