In Go, slices are a flexible and powerful way to work with sequences of elements. Whereas arrays have a fixed size, slices can be dynamically sized, making them particularly useful when working with collections of data. This article will guide you through the process of creating slices from arrays in Go, with examples from basic to advanced levels.

Basic Example: Creating a Slice from an Array

To start with, you might have an array, and you want to create a slice that references a subset of that array. Here's how you do it.


package main

import "fmt"

func main() {
    // Declare an array
    arr := [5]int{10, 20, 30, 40, 50}
    
    // Create a slice from the array
    slice := arr[1:4]
    // arr[1:4] means slice from index 1 to 3 (4 is exclusive)
    
    fmt.Println("Array: ", arr)
    fmt.Println("Slice: ", slice)
}

Output:


Array:  [10 20 30 40 50]
Slice:  [20 30 40]

Intermediate Example: Modifying Slices

Let's modify the slice and observe how it affects the original array. This demonstrates the concept that slices are references to arrays.


package main

import "fmt"

func main() {
    arr := [5]int{10, 20, 30, 40, 50}
    slice := arr[1:4]

    fmt.Println("Original slice:", slice)
    
    // Modify the slice
    slice[0] = 100

    fmt.Println("Modified slice:", slice)
    fmt.Println("Array after slice modification:", arr)
}

Output:


Original slice: [20 30 40]
Modified slice: [100 30 40]
Array after slice modification: [10 100 30 40 50]

Advanced Example: Slicing Beyond Array Capacity

In more advanced usage, you might want a slice to exceed the size or the boundary of an array. This leads to re-slicing and capacity management.


package main

import "fmt"

func main() {
    arr := [5]int{10, 20, 30, 40, 50}
    
    // Creating a slice that covers the entire array
    slice1 := arr[:]
    fmt.Println("Slice1 (entire array):", slice1)

    // Appending to the slice which exceeds its initial array's length
    slice2 := append(slice1, 60, 70)
    fmt.Println("Slice2 (appended):", slice2)
    
    // Note that appending elements beyond the array size creates a new underlying array.
    fmt.Println("Original array:", arr)
}

Output:


Slice1 (entire array): [10 20 30 40 50]
Slice2 (appended): [10 20 30 40 50 60 70]
Original array: [10 20 30 40 50]

This example shows that appending more elements than the capacity will move the data to a new larger array, leaving the original array unchanged.

Conclusion

Slices in Go offer a dynamic and efficient way to handle collections of data. Understanding slicing is essential for effective work in Go, allowing for coherent data structure management, efficient memory use, and flexible code design.