fabianoflorentino/golang-agent-skills

golang-pitfalls-data-types

Golang numeric types and data structures — octal literal confusion, integer overflow, floating-point approximations, slice length vs capacity, inefficient slice initialization, nil vs empty slices, emptiness checks, slice copies, append side effects, slice…

Vedi sorgente
Documento Skill originale

Contenuto dal repository con titoli, esempi, codice, tabelle, link e immagini preservati.

Golang Pitfalls: Data Types

Source material: mistakes #17-29 from 100 Go Mistakes and How to Avoid Them (teivah/100-go-mistakes).

Apply these rules when writing Go code around numeric types, slices, maps, and value comparison.

17. Octal literals confusion (#17)

  • Integer literals starting with 0 are octal (010 == 8 decimal).
  • Use explicit 0o prefix for octal (0o10) to avoid mistakes.
  • Other representations: binary 0b, hex 0x, imaginary i suffix; _ as digit separator (1_000_000_000, 0b00_00_01).

18. Neglecting integer overflows (#18)

  • Compile-time overflow/underflow of constants is an error; runtime overflow/underflow is silent — no panic.
  • This can turn positive additions into negative results. Write your own checks when overflow matters.
go
// silent at runtime
var counter int32 = math.MaxInt32
counter++ // wraps silently

19. Not understanding floating-points (#19)

  • float32/float64 are approximations, not exact real arithmetic (e.g., 1.0001 * 1.0001 prints 1.0002, not 1.00020001).
  • Compare floats by checking the difference is within a delta (e.g., math.Abs(a-b) <= delta).
  • Group additions/subtractions of similar order of magnitude for accuracy.
  • Do multiplication/division before addition/subtraction.

20. Slice length vs. capacity (#20)

  • Length: number of available elements. Capacity: number of elements in the backing array (from the slice's first element).
  • s := make([]int, 3, 6) → len 3, cap 6. Accessing s[3] panics even though memory is allocated.
  • append uses spare capacity; when the backing array is full, Go allocates a new array (doubling capacity), copies elements, and updates the pointer.
  • Slicing s2 := s1[1:3] shares the backing array; both see element updates. Appending to s2 within capacity mutates shared memory. Once an append forces a new array, s1 and s2 diverge.

21. Inefficient slice initialization (#21)

  • When the length is known, preallocate with make([]int, length) or make([]int, 0, capacity).
  • Avoid multiple copies and GC pressure. make([]int, length) tends to be slightly faster; make([]int, 0, cap) + append can be clearer.

22. Confusion about nil vs. empty slice (#22)

  • A nil slice equals nil; an empty slice has length 0 but isn't necessarily nil. A nil slice requires no allocation.
  • Initialization guidance:
  • var s []string — when unsure about final length and slice can be empty.
  • []string(nil) — syntactic sugar for a nil, empty slice.
  • make([]string, length) — known length.
  • Avoid []string{} when initializing without elements.
  • Check how libraries (e.g., encoding/json, reflect) distinguish nil vs empty to avoid surprises.

23. Not properly checking if a slice is empty (#23)

  • Check emptiness via len(s) == 0; it covers both nil and empty slices (same for maps).
  • Don't check s == nil to decide emptiness.
  • Design APIs that don't distinguish nil vs empty slices/maps — returning nil or empty should mean the same thing.

24. Not making slice copies correctly (#24)

  • copy(dst, src) copies min(len(dst), len(src)) elements.
  • Ensure the destination has enough length — allocate with make([]T, len(src)) first.

25. Unexpected side effects with slice append (#25)

  • When a slice's length is smaller than its capacity, append can mutate the backing array visible to other slices — a subtle side effect.
  • Prevent with full slice expression s[low:high:max] (sets capacity to max-low) or a slice copy.
  • Only a real copy prevents memory leaks when shrinking a large slice (see #26).

26. Slices and memory leaks (#26)

  • Leaking capacity: slicing a large array/slice keeps the whole backing array alive. Use a copy to release memory.
  • Slice of pointers / structs with pointer fields: GC won't reclaim elements excluded by slicing. Either copy or explicitly set remaining elements/fields to nil.

27. Inefficient map initialization (#27)

  • When the number of elements is known up front, create with initial size: make(map[string]int, n).
  • Avoids map growth (reallocation + rebalancing), which is expensive.

28. Maps and memory leaks (#28)

  • A Go map is a hash table: an array of bucket pointers, each bucket holds up to 8 key-value pairs (overflow creates chained buckets).
  • A map never shrinks — deleting elements zeroes slots but keeps the same number of buckets. Only a growing B field (log2 of #buckets) is possible.
  • After adding then deleting a million [128]byte values, heap stays ~293 MB (vs 461 MB peak) even after GC.
  • Mitigations:
  • Re-create/copy the map periodically (temporarily doubles memory).
  • Use pointers in values to shrink per-entry footprint when values are small: map[int]*[128]byte (38 MB vs 293 MB after GC).
  • Note: keys/values over 128 bytes are stored via pointers automatically.

29. Comparing values incorrectly (#29)

  • ==/!= work on comparable types: booleans, numbers, strings, channels (same make call or nil), interfaces (identical dynamic type & value), pointers, arrays/structs composed of comparable types.
  • Slices and maps are not comparable.
  • For non-comparable types use reflect.DeepEqual (correct but slow — reflection) or custom methods if performance matters.
  • Prefer existing optimized stdlib comparators (e.g., bytes.Compare) over reinventing the wheel.

Cross-References

  • → See fabianoflorentino/golang-agent-skills@golang-data-structures for slice/map/channel internals and usage
  • → See fabianoflorentino/golang-agent-skills@golang-performance for allocation-aware initialization
  • → See fabianoflorentino/golang-agent-skills@golang-safety for float comparison and nil-safety patterns
dallo stesso repository

Altri Skills

Tutti gli Skills
fabianoflorentino
Community

golang-design-patterns

Idiomatic Golang design patterns — functional options, constructor APIs, init() and global-state avoidance, enums, panic vs error decisions, resource management and lifecycle, graceful shutdown, timeouts and retries, streaming and iterators, and architecture styles (clean, hexagonal, DDD, flat). Apply when choosing between architectural patterns, implementing functional options, designing constructor APIs, setting up graceful shutdown, applying resilience patterns, or asking which idiomatic Go pattern fits a specific problem. Not for wiring a DI container or comparing DI libraries (→ See fabianoflorentino/golang-agent-skills@golang-dependency-injection skill), nor for error wrapping, errors.Is/As, or logging mechanics (→ See fabianoflorentino/golang-agent-skills@golang-error-handling skill).

installazioni
1
GitHub Stars
0
Aggiornato
14 set
fabianoflorentino
Community

golang-google-wire

Compile-time dependency injection in Golang using google/wire — wire.NewSet, wire.Build, wire.Bind (interface→concrete), wire.Struct, wire.Value, wire.InterfaceValue, wire.FieldsOf, cleanup functions, //go:build wireinject injector files, and generated wiregen.go. Apply when using or adopting google/wire, when the codebase imports github.com/google/wire, or when wiring an application graph at compile time via wire.Build. For runtime DI with reflection, see fabianoflorentino/golang-agent-skills@golang-uber-dig skill.

installazioni
1
GitHub Stars
0
Aggiornato
14 set
fabianoflorentino
Community

golang-lint

Linting best practices and golangci-lint configuration for Golang projects — running linters, configuring .golangci.yml, suppressing warnings with nolint directives, interpreting lint output, and selecting linters. Use when configuring golangci-lint, asking about lint warnings or nolint suppressions, setting up code quality tooling, or choosing linters. Also use when the user mentions golangci-lint, go vet, staticcheck, or revive. Not for wiring a lint step into a GitHub Actions pipeline (→ See fabianoflorentino/golang-agent-skills@golang-continuous-integration skill).

installazioni
1
GitHub Stars
0
Aggiornato
14 set
fabianoflorentino
Community

golang-modernize

Modernize Golang code to use recent language features, standard library improvements, and idiomatic patterns. Use when reviewing Go code with old-style patterns, when encountering a deprecation warning, or when the user asks for modernization, a Go version upgrade (e.g. to Go 1.27), or a CI/tooling refresh. Not for structural refactors, extracting functions, or moving code between packages (→ See fabianoflorentino/golang-agent-skills@golang-refactoring skill).

installazioni
1
GitHub Stars
0
Aggiornato
14 set