Go > Collections > Arrays and Slices > Appending to slices
Appending to Slices in Go
This code snippet demonstrates how to append elements to slices in Go, covering various scenarios like appending single elements, multiple elements, and even another slice.
Basic Append: Adding a Single Element
This is the simplest form of appending. The append
function takes the slice as the first argument and the element to append as the second. It returns a new slice with the element added. Crucially, the original slice variable is reassigned to point to this new slice. If the capacity of the original slice is sufficient, it may reuse the underlying array; otherwise, it will allocate a new, larger array and copy the contents.
package main
import "fmt"
func main() {
// Initialize a slice
slice := []int{1, 2, 3}
// Append a single element
slice = append(slice, 4)
fmt.Println(slice) // Output: [1 2 3 4]
}
Appending Multiple Elements
Go allows you to append multiple elements at once by passing them as additional arguments to the append
function. This is often more efficient than appending one element at a time.
package main
import "fmt"
func main() {
slice := []int{1, 2, 3}
// Append multiple elements
slice = append(slice, 4, 5, 6)
fmt.Println(slice) // Output: [1 2 3 4 5 6]
}
Appending Another Slice
To append all elements from one slice to another, you must use the spread operator (...
) after the slice you want to append. This unpacks the second slice into individual elements that are then appended to the first slice. Without the spread operator, you would be appending the entire slice as a single element (which would result in a [][]int
).
package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{4, 5, 6}
// Append slice2 to slice1 using the spread operator (...)
slice1 = append(slice1, slice2...)
fmt.Println(slice1) // Output: [1 2 3 4 5 6]
}
Concepts Behind Appending
Slices in Go are dynamic arrays. When you append to a slice, Go checks if the underlying array has enough capacity to accommodate the new elements. If it does, the new elements are added to the existing array. If not, Go allocates a new, larger array (usually doubling the capacity), copies the existing elements to the new array, and then adds the new elements. This can have performance implications, as frequent reallocations can be costly. Therefore, it's good practice to pre-allocate slices with sufficient capacity when you know the approximate size beforehand.
Real-Life Use Case
Appending to slices is commonly used when reading data from a file or a database where the number of records is not known in advance. You can start with an empty slice and append each record as it's read. For example, processing log files and collecting specific data points.
Best Practices
make([]T, 0, capacity)
. This avoids frequent reallocations.
Interview Tip
Be prepared to explain how append
works under the hood, including the concept of capacity and how it affects performance. Also, be ready to discuss the difference between length and capacity of a slice.
When to use them
Use append when you need a dynamically sized collection where elements are added sequentially. It's ideal for situations where the initial size is unknown or likely to change. Consider pre-allocation if performance is critical.
Memory Footprint
Appending might increase the memory usage especially when the underlying array needs to be reallocated. Be mindful of the growth pattern and try to optimize for minimizing reallocations. Also remember that even after an element is removed from a slice (via slicing), the underlying array might still hold the value (unless it's garbage collected). The length changes, but the capacity and underlying array might remain the same.
Alternatives
Pros
Cons
FAQ
-
What happens if I append to a nil slice?
Appending to a nil slice is perfectly valid in Go. Theappend
function will create a new slice with the specified element(s). -
Does appending modify the original slice?
No,append
returns a new slice. You need to reassign the result ofappend
back to the original slice variable if you want to update it. -
How can I avoid unnecessary reallocations?
Pre-allocate the slice with sufficient capacity usingmake([]T, 0, capacity)
.