Effective Go Style Guide Summary
This document summarizes key rules and best practices from the official "Effective Go" guide for writing idiomatic Go code.
1. Formatting
gofmt: All Go code must be formatted withgofmt(orgo fmt). This is a non-negotiable, automated standard.- Indentation: Use tabs for indentation (
gofmthandles this). - Line Length: Go has no strict line length limit. Let
gofmthandle line wrapping.
2. Naming
MixedCaps: UseMixedCapsormixedCapsfor multi-word names. Do not use underscores.- Exported vs. Unexported: Names starting with an uppercase letter are exported (public). Names starting with a lowercase letter are not exported (private).
- Package Names: Short, concise, single-word, lowercase names.
- Getters: Do not name getters with a
Getprefix. A getter for a field namedownershould be namedOwner(). - Interface Names: One-method interfaces are named by the method name plus an
-ersuffix (e.g.,Reader,Writer).
3. Control Structures
if: No parentheses around the condition. Braces are mandatory. Can include an initialization statement (e.g.,if err := file.Chmod(0664); err != nil).for: Go's only looping construct. Unifiesforandwhile. Usefor...rangeto iterate over slices, maps, strings, and channels.switch: More general than in C. Cases do not fall through by default (usefallthroughexplicitly). Can be used without an expression to function as a cleanerif-else-ifchain.
4. Functions
- Multiple Returns: Functions can return multiple values. This is the standard way to return a result and an error (e.g.,
value, err). - Named Result Parameters: Return parameters can be named. This can make code clearer and more concise.
defer: Schedules a function call to be run immediately before the function executingdeferreturns. Use it for cleanup tasks like closing files.
5. Data
newvs.make:new(T): Allocates memory for a new item of typeT, zeroes it, and returns a pointer (*T).make(T, ...): Creates and initializes slices, maps, and channels only. Returns an initialized value of typeT(not a pointer).
- Slices: The preferred way to work with sequences. They are more flexible than arrays.
- Maps: Use the "comma ok" idiom to check for the existence of a key:
value, ok := myMap[key].
6. Interfaces
- Implicit Implementation: A type implements an interface by implementing its methods. No
implementskeyword is needed. - Small Interfaces: Prefer many small interfaces over one large one. The standard library is full of single-method interfaces (e.g.,
io.Reader).
7. Concurrency
- Share Memory By Communicating: This is the core philosophy. Do not communicate by sharing memory; instead, share memory by communicating.
- Goroutines: Lightweight, concurrently executing functions. Start one with the
gokeyword. - Channels: Typed conduits for communication between goroutines. Use
maketo create them.
8. Errors
errortype: The built-inerrorinterface is the standard way to handle errors.- Explicit Error Handling: Do not discard errors with the blank identifier (
_). Check for errors explicitly. panic: Reserved for truly exceptional, unrecoverable situations. Generally, libraries should not panic.
Source: Effective Go