Middle · Go foundations
Everything is passed by value
If Go passes by value, why can a function modify a caller's slice elements?
Try explaining this aloud before opening the answer. State your assumptions and trace a boundary case.
Reveal a strong answer
Function arguments are copied values. Copying a slice copies a descriptor referring to the same backing storage; copying a pointer copies an address, and copying a map value still refers to the same map data.
Reassigning the local slice variable changes only that local descriptor. Mutating an existing element can be visible to the caller. Appending may allocate, so return the updated slice rather than assume the caller's length changes.
Copying a struct copies its fields, not a recursively independent object graph. A struct containing a slice or pointer can still share mutable data. Do not copy synchronization values such as an already-used mutex.
Common trap
“Slices are passed by reference” hides the copied descriptor and leads to wrong expectations about append.
Try it
A function appends to its []int argument but does not return it. Does the caller's length change?
Worked solution
No. The function changed its local slice descriptor. Writes into shared backing capacity may still affect other views, which is precisely why returning the descriptor and defining ownership matters.
Change the constraint
How would you design an API that promises it will not retain or mutate a caller's buffer?
How did you do?
Self-assessment, not a compiler pass or interview score. Explain the reasoning unaided before marking understood.
Not marked. Progress stays on this browser, separate from course completion.
Primary references
Checked 2026-10-20. Use documentation for your pinned runtime, driver and tool version.