Copy A Slice Safely
Fast recall
Quick revision
Core answer
Practical understanding of Slice Tricks.
Repeating a definition without saying when to use it.
Give one trade-off and say how you would test it.
Interview-ready guide
Interview answer
The safe copies are the two that guarantee new backing storage:
// explicit — capacity known
dst := make([]int, len(s))
copy(dst, s)
// idiom — one line, append picks capacity
v := append([]int(nil), s...)Both leave you with an independent slice: writes to dst don't appear in s and vice versa. The test is exactly that:
dst[0] = 50
fmt.Println(s[0]) // original value — untouchedWhat is NOT a copy: t := s. That shares the header — same backing array — which is the aliasing behavior, not the isolation behavior. (Verified: after t[0] = 100 through a plain assignment, s[0] reads 100.)
The boundary case that bites in practice: a slice of POINTERS. copy and the append-idiom both copy the pointer values — new headers, same pointees. *dst[0] = x still reaches the object s[0] points at. For pointer elements, slice-level copying is shallow by construction; deep isolation requires copying the pointed-to values, which is your code, not the language's.
Copy A Slice Safely
Direct Answer
make+copy: dst := make([]T, len(s)); copy(dst, s) — or append([]T(nil), s...). Both give new backing storage; t := s shares.
Deep Dive & Architecture
The two safe forms differ in who chooses capacity — and that's the whole choice between them.
make+copy: you chose. dst has exactly len(s) capacity — no waste, no headroom. The next append to dst allocates. Use when the copy is final-size.
append-idiom: append chose. The result's capacity is whatever growth policy gave — often more than len. Subsequent appends may fit without allocating. Use when the copy keeps growing.
The pointer-element boundary, verified: for []*int, both forms copy the pointer values — new headers, same pointees. *dst[0] = 99 is visible through src[0]. The slice-level safety is intact; the data-level sharing is unchanged. Deep copies are manual — copy the elements AND their pointees — there is no language-level deep copy, by design, because 'deep' is type-specific (what counts as deep for a struct containing a map?).
The test of a real copy — the one the executed examples ran: mutate the copy, print the source, see no change. Any copy idiom that fails that test is an alias (t := s and friends).
Common Mistakes & Pitfalls
Repeating a definition without saying when to use it.
Check your understanding
Answer these without looking back at the article.
- What is Slice Tricks, and when would you use it?
- When would you use Slice Tricks in a real project?
- How would you compare Slice Tricks with an alternative?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.