Go > Collections > Arrays and Slices > Slicing operations
Slicing a Slice in Go
This snippet demonstrates how to create new slices from existing slices using slicing operations in Go. Slicing allows you to extract portions of a slice without copying the underlying data, making it efficient for working with collections.
Basic Slicing Syntax
The syntax for slicing is slice[start:end]
, where start
is the index of the first element to include (inclusive) and end
is the index of the element to exclude (exclusive). Omitting start
defaults to 0, and omitting end
defaults to the length of the slice. A slice created with [:]
effectively creates a new slice that refers to the same underlying array. Modifying elements in this new slice will affect the original slice.
package main
import "fmt"
func main() {
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
// Create a slice from index 2 up to (but not including) index 5
subSlice1 := numbers[2:5]
fmt.Println("numbers[2:5]:", subSlice1) // Output: [2 3 4]
// Create a slice from the beginning up to (but not including) index 3
subSlice2 := numbers[:3]
fmt.Println("numbers[:3]:", subSlice2) // Output: [0 1 2]
// Create a slice from index 7 to the end
subSlice3 := numbers[7:]
fmt.Println("numbers[7:]:", subSlice3) // Output: [7 8 9]
// Create a slice that is a copy of the entire original slice
subSlice4 := numbers[:]
fmt.Println("numbers[:]:", subSlice4) // Output: [0 1 2 3 4 5 6 7 8 9]
}
Concepts Behind Slicing
Slices in Go are descriptors of array segments. They contain a pointer to the underlying array, a length (the number of elements the slice holds), and a capacity (the number of elements in the underlying array, starting from the first element in the slice). Slicing creates a new slice that points to the same underlying array segment. This is crucial for understanding that modifications made through one slice can affect others.
Real-Life Use Case: Pagination
Slicing is extremely useful for implementing pagination in web applications or data processing tasks. This example demonstrates how to extract a specific page of data from a larger dataset using slicing. The paginate
function takes a slice of strings, a page number, and a page size, and returns a slice containing the items for that page.
package main
import "fmt"
func paginate(items []string, pageNumber, pageSize int) []string {
start := (pageNumber - 1) * pageSize
if start > len(items) {
return []string{}
}
end := start + pageSize
if end > len(items) {
end = len(items)
}
return items[start:end]
}
func main() {
data := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}
page1 := paginate(data, 1, 3)
fmt.Println("Page 1:", page1) // Output: Page 1: [a b c]
page2 := paginate(data, 2, 3)
fmt.Println("Page 2:", page2) // Output: Page 2: [d e f]
page4 := paginate(data, 4, 3)
fmt.Println("Page 4:", page4) // Output: Page 4: [j]
page5 := paginate(data, 5, 3)
fmt.Println("Page 5:", page5) // Output: Page 5: []
}
Best Practices
copy()
if only a small portion is needed.for index, value := range slice
) for cleaner and safer code.
Interview Tip
A common interview question is to explain the difference between arrays and slices in Go, and how slicing works. Be prepared to discuss the concept of underlying arrays, length, capacity, and how modifications to a slice can impact other slices that share the same underlying array. Also, be ready to discuss scenarios where slicing can be used for efficient data manipulation.
When to Use Slicing
Use slicing when you need to:
Memory Footprint
Slicing itself has a low memory footprint because it only creates a new slice header (a pointer, length, and capacity). However, the underlying array is not copied, so the memory occupied by the array remains the same. The key consideration is whether the underlying array is kept alive longer than necessary due to a long-lived slice, potentially preventing garbage collection.
Alternatives
copy()
function to create a new slice and copy the data.
Pros
Cons
FAQ
-
What happens if the slice indices are out of bounds?
Go will panic with a runtime error if the slice indices are out of bounds during slicing. Specifically,start
must be less than or equal toend
, andend
must be less than or equal to the length of the slice. -
Does slicing create a new array?
No, slicing does not create a new array. It creates a new slice that refers to a portion of the existing array. The underlying array remains the same. -
How can I create a copy of a slice?
Use thecopy()
function. Create a new slice with the desired capacity and then usecopy(destinationSlice, sourceSlice)
to copy the elements from the source slice to the destination slice.