golang/go
Patterns and conventions
Go's house style is famously prescriptive. This page captures the conventions that this repository follows and that reviewers will enforce on CLs. They go beyond the public "Effective Go" guide.
Formatting
gofmtis non-negotiable. Every.gofile is formatted withgofmt. The pre-commit hook installed bygit codereview hooksruns it; CLs that aren't gofmt-clean are rejected.- Tabs for indentation, spaces for alignment. This is what
gofmtproduces. - Line length is unlimited in source. Wrap long argument lists naturally; do not break a line just because it crosses 80 columns.
- Comment lines wrap at ~76 columns so godoc and reviewers can read them comfortably.
Naming
- MixedCaps, never
snake_caseorSCREAMING_CAPS. Even constants. - Exported names start with an uppercase letter. Unexported start lowercase. There are no other visibility levels.
- Package names are short, lowercase, single words. Avoid
util,common, orhelpers. The package's name is the import path leaf. - Receiver names are short. One or two letters keyed off the type name. The same receiver name across all methods of a type. Don't use
self,this, orme. - Errors: values named
err; variables namederrFoofor sentinels (io.EOFis the famous exception); types namedFooError. - Tests:
TestFoo,BenchmarkFoo,ExampleFoo,FuzzFoo. The harness is built insrc/testing/. - Generated code: files containing
// Code generated by ... DO NOT EDIT.are exempt from formatting/style review and lint.
Documentation comments
- Every exported declaration has a doc comment. The first sentence starts with the name being documented:
// Read reads up to len(p) bytes into p. It returns ... func (f *File) Read(p []byte) (n int, err error) { ... } - Package comments live in a single file (often
doc.go) and start with// Package foo provides .... - Use plain prose, not "see [link]" — godoc cross-links automatically by name.
- Doc comments may use simple Markdown-like syntax in modern Go (headings, lists, links) — see the
go/doc/commentpackage.
Error handling
- No exceptions. Errors are values. Functions that can fail return
(T, error). - Error checks come first:
x, err := foo() if err != nil { return err } use(x) - Wrap with context using
fmt.Errorf("...: %w", err). Useerrors.Isanderrors.Asto inspect. - Sentinel errors are exported variables (
io.EOF,os.ErrNotExist). Compare witherrors.Is(err, io.EOF). - Don't add useless context.
fmt.Errorf("error reading file: %w", err)is redundant whenerralready says "open foo.txt: no such file." Add information the caller doesn't have. - Don't log and return. Log or return, not both — the caller will log.
Inside the runtime, errors are different: most paths use panic for fatal conditions and direct status codes for expected ones. See src/runtime/error.go.
Internal packages
internal/ is enforced by the build system: only the parent package and its descendants can import a package under .../internal/.... The standard library uses src/internal/ heavily for shared helpers (e.g., internal/abi, internal/byteorder, internal/race, internal/sync, internal/poll).
Use internal/ whenever code is needed in multiple packages but should not be exposed to users.
//go: directives
Go's compiler honors a number of pragma-like comments. The most common in this repo:
| Directive | Meaning |
|---|---|
//go:nosplit |
No stack-grow prologue (low-level runtime only) |
//go:noinline |
Don't inline this function |
//go:linkname local remote |
Bind unexported symbol from another package (mostly runtime ↔ stdlib) |
//go:noescape |
Tell compiler this assembly function does not escape its arguments |
//go:nowritebarrier / //go:nowritebarrierrec |
Forbid write barriers (runtime / GC code) |
//go:build linux && amd64 |
Build constraint |
//go:embed file.txt |
Embed file contents into a string or []byte |
//go:generate go run gen.go |
Run a generator on go generate |
//go:fix inline (and others) |
New //go:fix directives drive the go fix workflow |
//go:linkname is the runtime's escape valve. Use it sparingly and only when there is no public API alternative.
Build constraints
The new form is //go:build expr. The old form // +build is mirrored on the same file but is being phased out. gofmt keeps them in sync.
Common patterns:
//go:build !windows//go:build amd64 || arm64//go:build go1.21//go:build cgo
File-name suffixes (_linux.go, _amd64.go, _test.go) are also build constraints, applied automatically.
Concurrency idioms
- Don't communicate by sharing memory; share memory by communicating. Channels and
syncprimitives are both fine; pick the simpler one. sync.RWMutexis rarely worth the overhead. Plainsync.Mutexis faster for short critical sections.select { default: }for non-blocking channel ops.context.Contextis the first parameter of every blocking or long-running call. Never store acontext.Contextin a struct.go func()requires an exit story. A goroutine that never returns is a leak.- Don't use
time.Sleepfor synchronization. Use channels,sync.Cond, orsync.WaitGroup.
Testing idioms
- Subtests with
t.Runfor table-driven tests. t.Cleanup(fn)for setup/teardown instead ofdefer.t.Helper()in helper functions so failures point at the call site.- Golden files in
testdata/. A-updateflag is conventional for regenerating them. internal/testenvhasMustHaveExternalNetwork,MustHaveCgo,MustHaveExec, etc. Use them so tests skip cleanly on restricted builders.- Avoid hard-coded ports. Use
net.Listen("tcp", "localhost:0")to get an OS-assigned port.
Imports
Imports are formatted by goimports (a superset of gofmt). The standard convention is three groups separated by blank lines:
import (
"fmt"
"os"
"golang.org/x/sys/unix"
"github.com/example/foo"
)In this repo, only the first two groups exist (no third-party imports allowed in the standard library; golang.org/x/... is vendored under src/vendor/).
Cross-references
- Development workflow — Gerrit and CL flow.
- Testing — what to run.
- Tooling —
go generate,cmd/api, vet. - Components → Runtime — special rules for runtime code.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.