Go 1.27 essentials
A printable reference for Go syntax, concurrency, standard-library boundaries, tests, benchmarks, and diagnostic commands.
Go 1.27 1 page when printed
Declarations and control
package main place executable entry code in the main package var count int declare an integer initialized to its zero value name := "gopher" declare and infer a local variable in the current block left, right = right, left swap values after evaluating both right-hand expressions for i := range 10 { use(i) } iterate with i from zero through nine if value, ok := lookup(); ok { use(value) } branch on a result and status with local scope Functions and methods
func add(a, b int) int { return a + b } declare a function with grouped parameter types func load(id string) (Item, error) return a value together with an error func join(parts ...string) string accept zero or more trailing arguments func (c Counter) Value() int declare a method with a value receiver func (c *Counter) Increment() use a pointer receiver to mutate the referenced value func (s Stream[T]) Map[U any](f func(T) U) Stream[U] declare a method-specific type parameter in Go 1.27 Structs and interfaces
type User struct { ID int; Name string } define a struct with exported named fields user := User{ID: 7, Name: "Ana"} construct a struct with field names type Reader interface { Read([]byte) (int, error) } describe one required behavior type ReadWriter interface { io.Reader; io.Writer } compose interfaces by embedding them var _ io.Reader = (*bytes.Buffer)(nil) check interface satisfaction at compile time value, ok := input.(string) assert a dynamic type without panicking on mismatch Slices and maps
items := make([]Item, 0, capacity) create an empty slice with reserved capacity items = append(items, value) retain the slice returned by append clone := slices.Clone(items) copy elements into an independent backing array counts := make(map[string]int) create a writable map with comparable string keys count, ok := counts[key] distinguish an absent key from a stored zero value delete(counts, key) remove a key; absence is harmless keys := slices.Sorted(maps.Keys(counts)) collect map keys in deterministic sorted order Errors and cleanup
if err != nil { return fmt.Errorf("load %q: %w", id, err) } add context while preserving the error chain errors.Is(err, fs.ErrNotExist) match a target through wrappers and joined errors var pathErr *fs.PathError; errors.As(err, &pathErr) extract the first matching typed error errors.Join(errs...) combine non-nil failures into one traversable error defer file.Close() schedule cleanup when the surrounding function returns defer func() { if r := recover(); r != nil { handle(r) } }() recover only during deferred unwinding in the same goroutine Goroutines and channels
go process(job) start a concurrent call without waiting for its result jobs := make(chan Job, 8) create a channel that buffers up to eight values jobs <- job send, blocking when no receiver or buffer slot is ready job, ok := <-jobs receive and detect when a closed channel is drained close(jobs) signal that no more values will be sent; close from the sender select { case result := <-done: use(result); case <-ctx.Done(): return ctx.Err() } wait for a result or cancellation Context and synchronization
ctx, cancel := context.WithTimeout(parent, 2*time.Second); defer cancel() set a deadline and release its resources on every exit ctx, cancel := context.WithCancelCause(parent) derive a context whose cancel function records an error context.Cause(ctx) read the recorded cancellation cause var wg sync.WaitGroup; wg.Go(task); wg.Wait() start a non-panicking task and wait for it mu.Lock(); defer mu.Unlock() unlock a critical section on every function exit once.Do(initialize) run initialization at most once across goroutines value := counter.Add(1) atomically increment a typed atomic counter I/O and encoding
reader := bufio.NewReader(source) add buffered reads around an io.Reader n, err := io.Copy(dst, src) stream bytes until EOF or the first error data, err := io.ReadAll(io.LimitReader(src, limit)) read at most limit bytes into memory data, err := json.Marshal(value) encode a supported Go value as JSON err := json.Unmarshal(data, &dst) decode JSON into a pointer destination before, after, found := strings.Cut(text, separator) split once and report whether the separator existed //go:embed templates/*.html embed matching files in the following variable HTTP and SQL
mux.HandleFunc("GET /users/{id}", handler) route one HTTP method and path pattern id := r.PathValue("id") read a named ServeMux path wildcard req, err := http.NewRequestWithContext(ctx, method, url, body) bind cancellation and deadlines to an outbound request resp, err := client.Do(req) send the request; check err before using resp defer resp.Body.Close() release the response body after a successful Do err := db.QueryRowContext(ctx, query, args...).Scan(&dst) execute and scan a query expected to return one row tx, err := db.BeginTx(ctx, nil) start a transaction governed by the context Modules and build
go mod init example.com/project create a module with its import-path prefix go get example.com/[email protected] require or upgrade a dependency at an exact version go mod tidy synchronize go.mod and go.sum with package imports go fmt ./... format every package in the module go vet ./... run standard static analyzers across the module go generate ./... run source generators named by go:generate directives go build ./... compile every package without installing it Tests and fuzzing
func TestLoad(t *testing.T) declare a test discovered by go test t.Run(name, testCase) run a named subtest with a func(*testing.T) t.Cleanup(release) register cleanup after the test and its subtests finish go test -race ./... run all tests with the race detector go test -coverprofile=cover.out ./... write a statement-coverage profile func FuzzParse(f *testing.F) declare a fuzz test with a seed corpus go test -fuzz=FuzzParse -fuzztime=30s fuzz one matching target for thirty seconds Benchmarks and profiles
func BenchmarkEncode(b *testing.B) { for b.Loop() { encode(input) } } measure one operation per iteration with untimed outer setup b.Run(name, benchmarkCase) run a named sub-benchmark b.RunParallel(func(pb *testing.PB) { for pb.Next() { work() } }) distribute benchmark iterations across goroutines go test -run=^$ -bench=. -benchmem -count=10 skip tests and collect repeated time and allocation results benchstat old.txt new.txt compare benchmark samples statistically go test -run=^$ -bench=. -cpuprofile=cpu.prof capture CPU samples while benchmarks run go tool pprof -http=:0 cpu.prof inspect a profile in a local web interface Say it precisely to your AI
rules pack · Go
Go rules for your coding agent
Download the track's pitfalls and review checks in the format your coding agent reads.