|
| 1 | +# Effective Go Style Guide Summary |
| 2 | + |
| 3 | +This document summarizes key rules and best practices from the official "Effective Go" guide for writing idiomatic Go code. |
| 4 | + |
| 5 | +## 1. Formatting |
| 6 | +- **`gofmt`:** All Go code **must** be formatted with `gofmt` (or `go fmt`). This is a non-negotiable, automated standard. |
| 7 | +- **Indentation:** Use tabs for indentation (`gofmt` handles this). |
| 8 | +- **Line Length:** Go has no strict line length limit. Let `gofmt` handle line wrapping. |
| 9 | + |
| 10 | +## 2. Naming |
| 11 | +- **`MixedCaps`:** Use `MixedCaps` or `mixedCaps` for multi-word names. Do not use underscores. |
| 12 | +- **Exported vs. Unexported:** Names starting with an uppercase letter are exported (public). Names starting with a lowercase letter are not exported (private). |
| 13 | +- **Package Names:** Short, concise, single-word, lowercase names. |
| 14 | +- **Getters:** Do not name getters with a `Get` prefix. A getter for a field named `owner` should be named `Owner()`. |
| 15 | +- **Interface Names:** One-method interfaces are named by the method name plus an `-er` suffix (e.g., `Reader`, `Writer`). |
| 16 | + |
| 17 | +## 3. Control Structures |
| 18 | +- **`if`:** No parentheses around the condition. Braces are mandatory. Can include an initialization statement (e.g., `if err := file.Chmod(0664); err != nil`). |
| 19 | +- **`for`:** Go's only looping construct. Unifies `for` and `while`. Use `for...range` to iterate over slices, maps, strings, and channels. |
| 20 | +- **`switch`:** More general than in C. Cases do not fall through by default (use `fallthrough` explicitly). Can be used without an expression to function as a cleaner `if-else-if` chain. |
| 21 | + |
| 22 | +## 4. Functions |
| 23 | +- **Multiple Returns:** Functions can return multiple values. This is the standard way to return a result and an error (e.g., `value, err`). |
| 24 | +- **Named Result Parameters:** Return parameters can be named. This can make code clearer and more concise. |
| 25 | +- **`defer`:** Schedules a function call to be run immediately before the function executing `defer` returns. Use it for cleanup tasks like closing files. |
| 26 | + |
| 27 | +## 5. Data |
| 28 | +- **`new` vs. `make`:** |
| 29 | + - `new(T)`: Allocates memory for a new item of type `T`, zeroes it, and returns a pointer (`*T`). |
| 30 | + - `make(T, ...)`: Creates and initializes slices, maps, and channels only. Returns an initialized value of type `T` (not a pointer). |
| 31 | +- **Slices:** The preferred way to work with sequences. They are more flexible than arrays. |
| 32 | +- **Maps:** Use the "comma ok" idiom to check for the existence of a key: `value, ok := myMap[key]`. |
| 33 | + |
| 34 | +## 6. Interfaces |
| 35 | +- **Implicit Implementation:** A type implements an interface by implementing its methods. No `implements` keyword is needed. |
| 36 | +- **Small Interfaces:** Prefer many small interfaces over one large one. The standard library is full of single-method interfaces (e.g., `io.Reader`). |
| 37 | + |
| 38 | +## 7. Concurrency |
| 39 | +- **Share Memory By Communicating:** This is the core philosophy. Do not communicate by sharing memory; instead, share memory by communicating. |
| 40 | +- **Goroutines:** Lightweight, concurrently executing functions. Start one with the `go` keyword. |
| 41 | +- **Channels:** Typed conduits for communication between goroutines. Use `make` to create them. |
| 42 | + |
| 43 | +## 8. Errors |
| 44 | +- **`error` type:** The built-in `error` interface is the standard way to handle errors. |
| 45 | +- **Explicit Error Handling:** Do not discard errors with the blank identifier (`_`). Check for errors explicitly. |
| 46 | +- **`panic`:** Reserved for truly exceptional, unrecoverable situations. Generally, libraries should not panic. |
| 47 | + |
| 48 | +*Source: [Effective Go](https://go.dev/doc/effective_go)* |
0 commit comments