Slices in Go
Slices are one of the most important and commonly used data structures in Go. They provide a flexible and powerful way to work with collections of data.
While arrays have a fixed size, slices are dynamic and can grow or shrink as needed. Because of this flexibility, slices are preferred over arrays in most Go programs.
What Is a Slice?
A slice is a reference to a portion of an underlying array. It does not store data itself, but instead points to an array that holds the actual values.
Slices allow you to work with collections without worrying about fixed sizes.
Declaring a Slice
Slices can be declared without specifying a size.
package main
import "fmt"
func main() {
var numbers []int
fmt.Println(numbers)
}
This creates an empty slice of integers. The slice has no elements initially.
Creating a Slice Using Literals
The most common way to create a slice is using a slice literal.
package main
import "fmt"
func main() {
scores := []int{85, 90, 78, 88}
fmt.Println(scores)
}
Here, the slice automatically adjusts its size based on the number of elements provided.
Creating a Slice from an Array
Slices can be created by slicing an existing array.
package main
import "fmt"
func main() {
arr := [5]int{10, 20, 30, 40, 50}
slice := arr[1:4]
fmt.Println(slice)
}
This slice includes elements from index 1 up to (but not including) index 4.
Slice Length and Capacity
Slices have two important properties:
- Length: number of elements in the slice
- Capacity: number of elements available in the underlying array
package main
import "fmt"
func main() {
numbers := []int{10, 20, 30, 40, 50}
fmt.Println("Length:", len(numbers))
fmt.Println("Capacity:", cap(numbers))
}
Length represents how many elements are currently in the slice, while capacity represents how much the slice can grow.
Adding Elements to a Slice
Go provides the built-in append() function to add elements to a slice.
package main
import "fmt"
func main() {
numbers := []int{10, 20, 30}
numbers = append(numbers, 40, 50)
fmt.Println(numbers)
}
The append() function automatically increases the slice size when needed.
Iterating Over a Slice
Slices are commonly processed using loops.
package main
import "fmt"
func main() {
scores := []int{85, 90, 78, 88}
for i := 0; i < len(scores); i++ {
fmt.Println("Score:", scores[i])
}
}
Each iteration accesses one element of the slice.
Real-World Example: Monthly Expenses
Slices are ideal for handling data that grows over time, such as monthly expenses.
package main
import "fmt"
func main() {
expenses := []int{1200, 1500, 980}
expenses = append(expenses, 1100, 1600)
total := 0
for _, value := range expenses {
total += value
}
fmt.Println("Total Expenses:", total)
}
This program calculates the total expenses using a dynamically growing slice.
Slices vs Arrays
- Arrays have a fixed size
- Slices are dynamic and flexible
- Slices are more commonly used in real-world Go applications
- Slices provide better usability and scalability
Common Use Cases for Slices
- Handling user input data
- Processing lists of records
- Storing API responses
- Managing dynamic collections
What’s Next?
In the next lesson, you will learn about Maps in Go, which allow you to store data in key–value pairs for fast lookups.