| name | golang-style-guide |
| description | Go style and formatting guidelines: gofmt, goimports, naming conventions, comment standards, Effective Go idioms, and golangci-lint configuration. Use when reviewing or formatting Go code.
|
| allowed-tools | Bash(gofmt *), Bash(goimports *), Bash(golangci-lint *), Bash(revive *), Read, Grep |
Go Style Guide & Idioms
Go codebase consistency is paramount. The language relies heavily on conventions and
standardized tooling rather than strict rules enforced by the compiler.
This skill enforces Effective Go and Go Code Review Comments.
1. Tooling (Continuous Enforcement)
gofmt & goimports
Formatting is not a matter of preference in Go; it is strictly defined by gofmt.
goimports extends gofmt by organizing imports into standard library, external, and internal blocks.
goimports -l ./...
goimports -w ./...
gofmt -s -w ./...
golangci-lint (Style-specific linters)
linters:
enable:
- revive
- godot
- misspell
- unconvert
- goconst
- gofmt
- goimports
linters-settings:
revive:
rules:
- name: exported
- name: var-naming
- name: package-comments
- name: error-naming
- name: error-strings
- name: if-return
2. Naming Conventions
Package Names
- Short, concise, single word.
- Lowercase only. No
_ or mixedCaps.
- Descriptive. Name by what it provides, not what it contains.
- ❌
util, ❌ common, ❌ helpers, ❌ misc (Anti-patterns: meaningless)
- ✅
http, ✅ user, ✅ validate, ✅ json
Variable & Function Names
- MixedCaps / camelCase. (No
snake_case).
- Short scope = short name. e.g.,
i for index, r for Reader, err for error.
- Large scope = descriptive name. e.g.,
userCount, connectionString.
- Exported vs Unexported:
Process() is exposed outside the package.
process() is private to the package.
Interface Names
- One-method interfaces typically add an
-er suffix to the method name.
- e.g.,
Reader, Writer, Formatter, CloseNotifier.
Error Variables & Types
- Variables: Prefix with
Err.
- e.g.,
var ErrNotFound = errors.New(...)
- Types: Suffix with
Error.
- e.g.,
type ValidationError struct { ... }
3. Commenting & Documentation (Godoc)
Comments are for documentation. godoc expects specific formatting.
Exported Identifiers Must Be Commented
Every exported (capitalized) name in a program should have a doc comment.
type Request struct { ... }
func DoTheThing() error { ... }
Package Comments
Packages should have a package comment, introduced with // Package name...
It should be immediately before the package clause, with no blank line.
package math
4. Idioms & Best Practices (Effective Go)
Return Early (Avoid deep nesting)
func process(user *User) error {
if user != nil {
if user.IsActive {
return doWork(user)
} else {
return ErrInactive
}
}
return ErrNilUser
}
func process(user *User) error {
if user == nil {
return ErrNilUser
}
if !user.IsActive {
return ErrInactive
}
return doWork(user)
}
Zero Values Should Be Usable
Design structs so that their zero value (the default uninitialized state) is safe and useful.
sync.Mutex is ready to use without initialization.
bytes.Buffer is ready to use.
Accept Interfaces, Return Structs
Functions should accept the smallest interface they require, and return a concrete struct (if applicable).
This provides flexibility for the caller and avoids requiring them to cast interfaces.
func LoadUser(r io.Reader) (*User, error) { ... }
Group Related Declarations
Group related variables, constants, or types together.
const (
StatusActive = "active"
StatusInactive = "inactive"
)
5. Verification Commands
goimports -l ./...
golangci-lint run --enable=revive,godot,misspell,gofmt ./...