Top 10 Go Principles
A quick reference for how Go encourages you to structure code.
1. The entry point: explicit execution
Go does not allow "floating" code. Everything must be contained within a block. This keeps you from being surprised by side effects when you open a file.
- Rule: If it is not in a
func, it is not happening. - Blueprint:
func main()is the master toggle for your program.
2. The file system: packages as boundaries
The folder structure is the API boundary. You organize to define "who knows what."
- Rule: A package should do one thing (e.g.,
storehandles data,apihandles web). - Directional flow:
api→store(legal) |store→api(circular dependency error).
3. Data-centric logic: data owns behavior
Instead of creating "manager" classes, Go attaches functions directly to the data they modify.
- Method:
func (p Product) Calculate()attaches the logic to theProductstruct. - Mental model: The data carries its own toolbox.
4. The "valve": intentional mutation
Go makes you choose if a function can "write" to data or just "read" it.
- Value receiver (
p Product): A copy. Safe, no side effects. - Pointer receiver (
p *Product): The original. Allows modification. - Rule: Use
*when you need to change state; otherwise keep it read-only.
5. Flow control: errors as values
Go treats errors like any other piece of data. There is no hidden crash (exception). You must decide what to do immediately.
- Pattern:
result, err := DoWork() - Mental model: Every risky door returns both the prize and a status report.
6. Semantic clarity: domain types
Do not use string for everything. If a string is specifically a UserID, name it that.
- Rule:
type UserID stringprevents you from passing aPasswordinto a function expecting an ID.
7. Decoupling: consumer-defined interfaces
In other languages, a class says "I implement this interface." In Go, the caller defines the interface.
- Rule: If it walks and quacks like a duck, it is a duck. Match the signature, no declaration required.
8. Structural building: composition
Go avoids the family tree (inheritance) in favor of Lego bricks (composition).
- Pattern: To give a service logging, embed a
Logger. - Result: Flatter structures and less spaghetti logic.
9. Responsibilities: thin main, fat packages
The main.go file is the wiring closet. It connects the database to the server and gets out of the way.
- Rule: Business logic lives in packages; initialization lives in
main.
10. Communication: channels and concurrency
Go's motto: "Do not communicate by sharing memory; instead, share memory by communicating."
- Tool: Channels (
chan) act as conveyor belts between goroutines. - Rule: Use channels to orchestrate timing rather than guessing with
time.Sleep.