| # 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 with `gofmt` (or `go fmt`). This is a non-negotiable, automated standard. | |
| - **Indentation:** Use tabs for indentation (`gofmt` handles this). | |
| - **Line Length:** Go has no strict line length limit. Let `gofmt` handle line wrapping. | |
| ## 2. Naming | |
| - **`MixedCaps`:** Use `MixedCaps` or `mixedCaps` for 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 `Get` prefix. A getter for a field named `owner` should be named `Owner()`. | |
| - **Interface Names:** One-method interfaces are named by the method name plus an `-er` suffix (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. Unifies `for` and `while`. Use `for...range` to iterate over slices, maps, strings, and channels. | |
| - **`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. | |
| ## 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 executing `defer` returns. Use it for cleanup tasks like closing files. | |
| ## 5. Data | |
| - **`new` vs. `make`:** | |
| - `new(T)`: Allocates memory for a new item of type `T`, zeroes it, and returns a pointer (`*T`). | |
| - `make(T, ...)`: Creates and initializes slices, maps, and channels only. Returns an initialized value of type `T` (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 `implements` keyword 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 `go` keyword. | |
| - **Channels:** Typed conduits for communication between goroutines. Use `make` to create them. | |
| ## 8. Errors | |
| - **`error` type:** The built-in `error` interface 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](https://go.dev/doc/effective_go)* |