Writing idiomatic, effective, and clean Go code involves adhering to a set of principles and practices that leverage the language's unique design. Here are some key guidelines, often considered "commandments" in the Go community:
The Ten Commandments of Idiomatic Go:
-
Thou Shalt Format Thy Code with
golangci-lint:- Guideline: Use the
golangci-linttool religiously. It enforces a standard, opinionated style for indentation, spacing, and alignment. We support the tool directly in ourMakefile. You can run:
make lint
and
make checks
- This consistency makes Go code highly readable and reduces time spent on style debates. Many editors and IDEs integrate
gofmtautomatically on save. Thegoimportstool is a superset ofgofmtthat also manages imports. - References:
- Guideline: Use the
-
Thou Shalt Handle Errors Explicitly:
- Guideline: Go treats errors as values. Functions that can fail should return an error as the last return value.
Always check error returns and handle them gracefully. Avoid ignoring errors using the blank identifier
_. Propagate errors back up the call stack or handle them appropriately (e.g., logging, retrying). Useerrors.Isanderrors.Asfor checking error types or values, especially in Go 1.13+. Error strings should be lowercase and not end with punctuation. - References:
- Effective Go - Errors
- Golang 10 Best Practices - Proper Error Handling
- Go standards and style guidelines - GitLab Docs (Mentions
errors.Isanderrors.As)
- Guideline: Go treats errors as values. Functions that can fail should return an error as the last return value.
Always check error returns and handle them gracefully. Avoid ignoring errors using the blank identifier
-
Thou Shalt Favor Composition Over Inheritance:
- Guideline: Go does not have traditional class inheritance. Achieve code reuse and flexibility through composition (embedding structs) and interfaces. Design small, focused interfaces that define behavior.
- References:
-
Thou Shalt Design Small, Focused Interfaces:
- Guideline: Go's interfaces are implicitly implemented.
Define interfaces on the consumer side, specifying only the methods a client needs.
This promotes decoupling and testability.
Name interfaces with an "-er" suffix (e.g.,
Reader,Writer) when they define a single method, though this is a convention, not a strict rule for all interfaces. - References:
- Effective Go - Interfaces
- Golang style guide - Mattermost Developers (Mentions the "-er" convention)
- Guideline: Go's interfaces are implicitly implemented.
Define interfaces on the consumer side, specifying only the methods a client needs.
This promotes decoupling and testability.
Name interfaces with an "-er" suffix (e.g.,
-
Thou Shalt Write Concurrent Code Using Goroutines and Channels:
- Guideline: Embrace Go's built-in concurrency primitives. Use goroutines for concurrent execution and channels for safe communication and synchronization between them. Understand the Go memory model and use tools like the race detector to avoid race conditions.
- References:
-
Thou Shalt Not Use Global Variables Extensively:
- Guideline: Limit the use of global variables to avoid side effects and improve testability and maintainability. Pass data explicitly through function parameters and return values, or use struct fields.
- References:
- Golang 10 Best Practices - Minimize Global Variables
- Go standards and style guidelines - GitLab Docs (Avoid global variables)
-
Thou Shalt Keep Functions Small and Single-Purpose:
- Guideline: Design functions that do one thing well. Short, focused functions are easier to understand, test, and maintain. Avoid excessive nesting and complex logic within a single function.
- References:
-
Thou Shalt Write Tests:
- Guideline: Go has a built-in testing framework. Write unit tests for your code to ensure correctness and provide examples of how to use your functions and types. Table-driven tests are a common and effective pattern in Go.
- References:
- Effective Go - Testing
- Go standards and style guidelines - GitLab Docs (Defining test cases)
-
Thou Shalt Document Exported Symbols:
- Guideline: Provide clear and concise documentation for all exported functions, types, variables, and constants. Comments should explain what the code does and why, especially for non-obvious parts. Use Godoc conventions for easily generated documentation.
- References:
-
Thou Shalt Be Mindful of Performance and Allocations:
- Guideline: While Go is performant, be aware of potential bottlenecks. Understand how slices, maps, and pointers work to minimize unnecessary allocations and garbage collection pressure, especially in performance-critical code. Use tools like the pprof profiler to identify performance issues.
Additional Recommended Reading and Style Guides:
- Effective Go - A fundamental guide from the Go team on writing clear, idiomatic Go code.
- Go Code Review Comments - A wiki page listing common style issues and suggestions.
- Google Go Style Guide - Google's internal style guide for Go.
- Uber Go Style Guide - Uber's widely referenced style guide for Go.
These resources provide more detailed explanations and examples for each of the guidelines mentioned above, helping you to write more effective and idiomatic Go code.