Go structs are copied on assignment (and other things about Go I'd missed)
Go value semantics & common pitfalls
- Many comments reiterate that in Go everything is passed by value (copied), including pointers, slices, maps, and channels; what’s copied is often a small descriptor that points to shared backing data.
- A common gotcha: copying a struct, slice, or map variable copies the descriptor, so mutating through either copy can affect shared underlying data, but reassigning the local variable does not affect the original.
- Range loops can copy elements;
for _, v := range slicemay repeatedly copy large structs, with both correctness and performance implications. - Named return values can be silently left at their zero value (e.g.,
errstayingnil) if not explicitly assigned.
Pass-by-value vs pass-by-reference terminology
- Long debate over whether modern languages meaningfully distinguish “pass-by-value” and “pass-by-reference.”
- Several argue nearly all mainstream languages pass by value (often copying a pointer/reference), and that older “true pass-by-reference” semantics are largely historical.
- Others insist the distinction still matters (e.g., C++/C# reference parameters) and should be taught, especially for performance and expressiveness.
- Python’s model (variables as references to objects, arguments as copies of those references) is used extensively to illustrate confusion.
Slices, maps, and reference-like behavior
- Slices and maps are described as small structs containing pointers; copying them copies the struct, not the underlying storage.
- This leads to “reference-like” behavior that surprises newcomers, especially when appending to slices (which may reallocate and break sharing) versus mutating elements or map entries (which affects shared data).
- Some see this as clear and consistent once understood; others find the hidden sharing and performance characteristics non-obvious and error-prone.
Language design, safety, and ergonomics
- Some praise Go’s explicitness and C-like value semantics as easier to reason about than dynamic languages.
- Others view many of these pitfalls as avoidable language design mistakes and argue alternative languages (e.g., Rust) avoid them.
- There is recurring desire for better immutability and optional types in Go; attempts to retrofit immutability are said to be hard in an established language.
Learning, documentation, and expertise
- Strong recommendations to read the official spec and certain Go books; the spec is praised as clear and accessible.
- A Go “100 mistakes” collection is discussed: some find early items too basic, others defend starting simple and building up.
- Several comments value public admission of knowledge gaps as a healthy senior-engineer trait; dissenting voices argue that senior developers, especially listing Go on a CV, should already know these memory details.