Go slices versus Rust Vec growth and reallocation
understanding of dynamic-array internals.
both are a (pointer, length, capacity) triple over a heap buffer that reallocates and copies on growth, roughly doubling; key difference is Go slices share backing arrays and have no ownership…
WHAT THIS TESTS It verifies you understand the pointer/length/capacity model of dynamic arrays, the amortized reallocation behavior on growth, and the ownership and aliasing differences between the two languages.
A GOOD ANSWER COVERS Both types are a three-word header: a pointer to a contiguous heap-allocated buffer, a length (number of initialized elements), and a capacity (allocated slots). Reading and indexing are O(1). When you append beyond capacity, neither can grow in place reliably, so each allocates a new, larger buffer, copies the existing elements over, updates the pointer and capacity, and (in Rust) frees the old buffer. Growth is amortized O(1): the capacity grows by a multiplicative factor, commonly close to doubling for small sizes and a smaller factor as the slice gets large, so the total copying cost across many appends stays linear.
KEY DIFFERENCE A Go slice is a lightweight view into a backing array; multiple slices can share and alias the same array, and slicing does not copy. The slice does not own the array, and the garbage collector reclaims it. A Rust Vec<T> uniquely owns its buffer; ownership and borrowing rules prevent aliasing mutation, and the buffer is freed deterministically when the Vec is dropped. To get a non-owning view in Rust you use a slice type &[T].
COMMON WRONG ANSWERS Saying capacity equals length. Claiming the buffer grows in place without copying. Saying Go slices own their backing array, or forgetting that appending to a Go slice can leave other slices pointing at the old array.
LIKELY FOLLOW-UPS Why can appending to one Go slice silently stop reflecting in another that shared the array? What is the difference between Vec<T> and &[T]? How do you preallocate to avoid reallocations (make with capacity, Vec::with_capacity)?
ONE CONCRETE EXAMPLE In Go, b := append(a, x) may, if a is at capacity, allocate a new array and copy, so b and a then point at different arrays; if there was spare capacity, they share, and mutating b can affect a. In Rust, v.push(x) on a full Vec allocates a larger buffer, copies, frees the old one, and because the Vec owns the buffer exclusively, no other reference could have been aliasing it.
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.