Skip to content

Cheatsheet

Fast one-page lookup: everyday Go syntax and idioms up top, then the verified build/test/CLI commands and directory layout of a real Go system — multigres (“Vitess for Postgres”) — below. Each row links into the language and project tracks for depth.

FormExampleNotes
varvar n intzero value (0, "", nil)
:=n := 42short, function-scope only
constconst Max = 1 << 20compile-time
iotaconst ( A = iota; B; C )0,1,2 enum counter
multia, b := 1, 2tuple assign / swap a, b = b, a
s := make([]int, 0, 8) // len 0, cap 8
s = append(s, 1, 2) // grow (may realloc)
n := copy(dst, src) // n = min(len(dst), len(src))
s = s[2:5] // sub-slice (shares backing array)
clear(s) // zero all elements (Go 1.21+)

A sub-slice shares the backing array — appending into it can clobber the parent. See stdlib & idioms.

v, ok := m[k] // comma-ok: ok=false if absent
delete(m, k) // no-op if absent
for k, v := range m { ... } // unordered
clear(m) // remove all keys
if err != nil {
return nil, fmt.Errorf("doing X: %w", err) // wrap with %w
}

errors.Is(err, target) / errors.As(err, &t) to inspect. Depth: errors. In this codebase, errors at RPC/service boundaries use mterrors, not bare fmt.Errorf — see the mterrors section below.

go work() // fire-and-forget goroutine
ch := make(chan int, 4) // buffered (cap 4); unbuffered if no cap
ch <- v // send
v, ok := <-ch // receive; ok=false when closed and drained
close(ch) // sender closes, never the receiver
select {
case v := <-ch: ...
case ch2 <- x: ...
case <-ctx.Done(): return ctx.Err() // cancellation
default: ... // non-blocking
}

Depth: concurrency.

func Do(ctx context.Context, ...) error { // ctx is always the FIRST param
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel() // always defer cancel
...
}

Depth: context.

type Config struct {
Name string `json:"name"`
Port int `json:"port,omitempty"`
}

Backtick-quoted key:"value" metadata read by reflection (encoding, validation). Depth: stdlib & idioms.

func Map[T, U any](s []T, f func(T) U) []U { ... }
type Group[K comparable, V any] struct { ... } // K must be comparable

any = interface{}; comparable = usable with ==. A real example: func NewGroup[K comparable, V any]() *Group[K, V] in the codebase’s singleflight cache. Depth: generics.

defer f() // runs at function return, LIFO order
defer func() {
if r := recover(); r != nil { ... } // recover only inside a deferred func
}()

Deferred args are evaluated when defer runs, not when the function returns.

The examples below come from multigres: Go 1.25, a single module github.com/multigres/multigres, all code under go/. The build is Makefile-driven; make help auto-generates the target list from ## comments — a tidy pattern worth borrowing.

TargetDoes
make toolsInstall protobuf + build tools
make buildBuild all 7 binaries into bin/ (debug, with symbols)
make build-releaseStatic, stripped release binaries (CGO_ENABLED=0)
make build-allproto + parser + metrics + build
make protoRegenerate protobuf into go/pb
make parsergo generate the SQL parser: goyacc and asthelpergen
make metricsGenerate the Prometheus metric catalog
make generateAlias for parser + metrics (NOT proto)
make installInstall binaries to GOPATH/bin
make testRun all tests (starts the port-pool server)
make test-shortShort tests only
make test-raceTests with the race detector
make test-coverageComprehensive coverage
make clean / make clean-allRemove build artifacts / + deps
make validate-generated-filesCI check: regenerate everything and diff
make pgregress / pgexternal / pgprotoPostgreSQL regression / external-ext / wire-protocol suites

The 7 binaries are multigateway, multipooler, pgctld, multiorch, multigres, multiadmin, and portpoolserver, each built via go build -o bin/$cmd ./go/cmd/$cmd.

This codebase runs its tests through a dev wrapper rather than calling go test directly — integration runs need a shared port pool, or they collide flakily. The wrapper expands to ordinary go test invocations:

InvocationExpands to
unit allgo test -short ./go/...
unit <pkg> [TestName]go test [-run TestName] <pkg>
integration allmake build && go test ./go/test/endtoend/...
integration <pkg> [TestName]make build + start port pool + go test [-run TestName] ./go/test/endtoend/<pkg>/...

Integration <pkg> values: all, multipooler, multiorch, queryserving, localprovisioner, shardsetup, pgregresstest. Common flags: -v -race -cover -count=N -short -timeout.

The multigres binary doubles as the cluster-management CLI:

CommandDoes
./bin/multigres cluster initInitialize cluster config
./bin/multigres cluster startStart local cluster components
./bin/multigres cluster stop [--clean]Stop (--clean wipes state)
./bin/multigres cluster statusShow component status
./bin/multigres getpoolersList registered poolers
./bin/multigres getpoolerstatus --cell <cell> --service-id <id>Status of one pooler

Depth: cmd & cobra.

Project error constructors (where code is a protobuf RPC code):

mterrors.New(code, message)
mterrors.Errorf(code, format, args...)
mterrors.Wrap(err, message)
mterrors.Wrapf(err, format, args...)
mterrors.NewPgError(...) // Postgres wire errors

Use these at RPC/service boundaries; reserve stdlib fmt.Errorf("...: %w", err) for internal wrapping. Depth: mterrors & observability.

  • Directorygo/
    • Directorycmd/ entrypoints for the 7 binaries
    • Directoryservices/ service impls: multiadmin, multigateway, multiorch, multipooler, pgctld
    • Directorycommon/ shared libs: mterrors, parser, pgprotocol, sqltypes, consensus, servenv, …
    • Directorypb/ generated protobuf (output of make proto)
    • Directoryobservability/ generated metric catalog (output of make metrics)
    • Directorytest/endtoend/ integration tests
  • Directoryproto/ proto source files