# Go — Language Application > How Atelier's domain principles apply in Go specifically. Derives from `domains/` docs. ## Derived Docs - [go-types.md](go-types.md) — named types, generics, interfaces, type assertion discipline. - [go-tooling.md](go-tooling.md) — go vet, golangci-lint, go test -race, module discipline. - [go-concurrency.md](go-concurrency.md) — goroutines, channels, context, select, sync primitives. - [go-testing.md](go-testing.md) — table-driven tests, t.Parallel, t.Cleanup, race detector. ## Type System (C1 Correctness, Data P7 Type Fidelity) - **Named types for domain concepts:** `type UserId string`, not bare `string`. - **No `interface{}`/`any` without justification:** Go 1.18+ generics reduce the need. - **`any` requires a type assertion or switch:** never use the value without narrowing. ```go type UserId string type OrderId string // UserId and OrderId are distinct; cannot be mixed func GetUser(id UserId) (*User, error) { ... } ``` ## Error Handling (Errors P1 Errors are Data) - **Errors are values:** `error` is an interface, not an exception. Handle explicitly. - **Sentinel errors with `errors.Is`:** ```go var ErrNotFound = errors.New("not found") if errors.Is(err, ErrNotFound) { ... } ``` - **Wrap with context:** `fmt.Errorf("get user %d: %w", id, err)`. - **Never `_ = err`:** swallowed error (Errors P2). Handle or return. - **Custom error types with `errors.As`:** ```go type ValidationError struct { Field string Msg string } func (e *ValidationError) Error() string { return e.Field + ": " + e.Msg } ``` ## Concurrency (Concurrency — Go's strength) - **Goroutines + channels** for message passing (P5 Lock Minimization). - **`context.Context` for cancellation and timeout:** every function that does I/O takes a `ctx`. - **`sync.Mutex` scoped minimally:** not held across I/O (P3 Lock Scope). - **Bounded channels:** `make(chan T, N)`, not unbounded (P9 Bounded Queues). ```go func fetchWithTimeout(ctx context.Context, url string) (*Response, error) { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() return doFetch(ctx, url) } ``` ## Immutability (Concurrency P1) - **Pass by value for small structs; pass by pointer for large or mutable.** - **No mutation of method receivers:** use a value receiver, not a pointer receiver, for read-only methods. - **Copy-on-write for shared state:** return a new struct, not a mutated one. ## Nullability (C1) - **Pointers can be nil; values cannot.** Be explicit: `*User` (nullable) vs `User` (not). - **`nil` check before deref:** a nil deref is a panic. - **Return `(T, error)`, not `(*T, nil)`:** avoid the "nil pointer" trap. ## Testing (Testing) - **`testing` package + `testify/assert`** or stdlib only. - **Table-driven tests:** `[]struct{ name string; input X; want Y }`. - **`t.Parallel()`** for independent tests (P2 Independence). - **`httptest` for HTTP handlers; `sqlite` or testcontainers for DB.** ## Observability (Observability P1) - **`slog` (stdlib, Go 1.21+) or `zap`/`zerolog`:** structured logs. - **`context.Context` carries `trace_id`:** propagated via middleware. - **No `fmt.Println`:** use the logger. ## Tooling (DevOps P2) - **`go vet` + `golangci-lint`:** lint. - **`gofmt`/`goimports`:** format (automated, not debated). - **`go test -race` in CI:** race detector (Concurrency P6 No Silent Races). - **`go mod tidy` + committed `go.sum`:** reproducible builds.