Go Slice Default Capacity

In Go, slices are dynamic data structures that can grow or shrink. A slice has two main attributes: length and capacity. The capacity of a slice determines the maximum number of elements it can hold before needing to allocate more memory.

In this tutorial, we will explore how to determine the default capacity of slices, examine how capacity changes dynamically, and provide examples with detailed explanations.


Default Capacity of a Slice

  • When Using make: The default capacity equals the specified length if only the length is provided.
  • When Using a Literal: The capacity equals the number of elements in the slice literal.
  • Dynamic Growth: If the slice grows beyond its capacity, Go allocates a new underlying array with increased capacity (typically doubling the previous capacity).

Examples of Slice Capacity

1. Default Capacity with make

This example demonstrates the default capacity of a slice created using the make function:

</>
Copy
package main

import "fmt"

func main() {
    // Create a slice with make, specifying only the length
    slice := make([]int, 5)

    // Print the length and capacity
    fmt.Println("Length:", len(slice))
    fmt.Println("Capacity:", cap(slice))
}

Explanation for Example 1: Default Capacity with make

  1. Slice Creation: The slice is created using make([]int, 5), which initializes the slice with a length of 5.
  2. Default Capacity: Since only the length is provided, the default capacity of the slice is equal to the specified length, which is 5.
  3. Print Length and Capacity: The len(slice) and cap(slice) functions are used to retrieve and display the slice’s length and capacity, both of which return 5.

Output


2. Specifying Length and Capacity with make

This example demonstrates how to create a slice with a custom capacity using the make function:

</>
Copy
package main

import "fmt"

func main() {
    // Create a slice with make, specifying length and capacity
    slice := make([]int, 3, 10)

    // Print the length and capacity
    fmt.Println("Length:", len(slice))
    fmt.Println("Capacity:", cap(slice))
}

Explanation

  1. Slice Creation: The slice is created using make([]int, 3, 10), where the length is specified as 3 and the capacity as 10.
  2. Custom Capacity: By explicitly providing the capacity, the slice is created with additional memory allocation for up to 10 elements.
  3. Print Length and Capacity: The len(slice) and cap(slice) functions are used to display the length as 3 and the capacity as 10.

Output


3. Capacity with Slice Literals

This example demonstrates the default capacity of a slice created using a slice literal:

</>
Copy
package main

import "fmt"

func main() {
    // Create a slice using a literal
    slice := []int{1, 2, 3, 4}

    // Print the length and capacity
    fmt.Println("Length:", len(slice))
    fmt.Println("Capacity:", cap(slice))
}

Explanation

  1. Slice Creation: The slice is created using a literal []int{1, 2, 3, 4}, which directly initializes the slice with four elements.
  2. Default Capacity: For a slice literal, the capacity is equal to the number of elements in the literal, which is 4.
  3. Print Length and Capacity: The len(slice) and cap(slice) functions are used to retrieve and display the length and capacity, both of which are 4.

Output


4. Dynamic Growth of Slice Capacity

This example demonstrates how the capacity of a slice grows dynamically when elements are appended beyond its initial capacity:

</>
Copy
package main

import "fmt"

func main() {
    // Create a slice with make
    slice := make([]int, 3, 3)

    // Print initial capacity
    fmt.Println("Initial Capacity:", cap(slice))

    // Append elements beyond initial capacity
    slice = append(slice, 4, 5, 6, 7)

    // Print new capacity
    fmt.Println("New Capacity:", cap(slice))
}

Explanation

  1. Initial Slice Creation: The slice is created using make([]int, 3, 3), initializing it with a length and capacity of 3.
  2. Initial Capacity: The capacity is retrieved using cap(slice) and printed as 3.
  3. Appending Elements: Additional elements are appended to the slice using append(slice, 4, 5, 6, 7), exceeding the initial capacity.
  4. Capacity Growth: When the slice exceeds its initial capacity, Go automatically reallocates a larger underlying array, typically doubling the capacity. The new capacity is retrieved using cap(slice) and printed as 6.

Output


Points to Remember

  • Default Capacity: When creating slices with make, the default capacity equals the specified length unless a custom capacity is provided.
  • Dynamic Growth: Go slices automatically grow in capacity when needed, usually doubling the previous capacity.
  • Optimize Capacity: Specify an appropriate capacity during slice creation to reduce memory reallocations and improve performance.
  • Use cap: The built-in cap function allows you to determine the capacity of a slice at runtime.