ZetCode

Golang cap function

last modified May 8, 2025

This tutorial explains how to use the cap built-in function in Go. We'll cover slice and array capacity with practical examples of capacity usage.

The cap function returns the capacity of a slice or array in Go. Capacity represents the maximum number of elements the underlying array can hold. For arrays, capacity is always equal to length.

In Go, cap is primarily used with slices to understand their growth potential. Knowing a slice's capacity helps optimize memory usage and performance.

Basic array capacity example

For arrays, cap always returns the same value as len. This example demonstrates capacity with a fixed-size array.
Note: Arrays have fixed capacity determined at declaration.

array_cap.go
package main

import "fmt"

func main() {
    arr := [5]int{1, 2, 3, 4, 5}
    
    fmt.Println("Array:", arr)
    fmt.Println("Length:", len(arr))
    fmt.Println("Capacity:", cap(arr)) // Same as length for arrays
}

The array has fixed size 5, so both length and capacity are 5. Capacity cannot change for arrays after declaration.

Slice capacity basics

Slices can grow up to their capacity before needing reallocation. This example shows how slice capacity differs from length.

slice_cap.go
package main

import "fmt"

func main() {
    s := make([]int, 3, 5) // length 3, capacity 5
    
    fmt.Println("Slice:", s)
    fmt.Println("Length:", len(s))
    fmt.Println("Capacity:", cap(s))
    
    s = append(s, 4)
    fmt.Println("\nAfter append:")
    fmt.Println("Length:", len(s))
    fmt.Println("Capacity:", cap(s)) // Still 5
}

The slice starts with length 3 but capacity 5. After appending one element, length becomes 4 while capacity remains 5.

Capacity growth with append

When a slice exceeds its capacity, Go automatically allocates a new larger array. This example demonstrates capacity growth during append operations.

capacity_growth.go
package main

import "fmt"

func main() {
    s := make([]int, 0, 2) // length 0, capacity 2
    
    fmt.Printf("Initial cap: %d\n", cap(s))
    
    s = append(s, 1)
    s = append(s, 2)
    fmt.Printf("After 2 appends cap: %d\n", cap(s))
    
    s = append(s, 3) // Exceeds capacity
    fmt.Printf("After 3rd append cap: %d\n", cap(s)) // Capacity doubles
}

When exceeding initial capacity, Go typically doubles the capacity. This growth pattern helps amortize allocation costs over multiple append operations.

Capacity of slice expressions

Slice operations affect capacity differently. This example shows how slicing impacts capacity calculations.

slice_expression_cap.go
package main

import "fmt"

func main() {
    original := make([]int, 5, 10) // length 5, capacity 10
    
    // Full slice
    fmt.Printf("Original cap: %d\n", cap(original))
    
    // Slice from index 2
    slice1 := original[2:]
    fmt.Printf("Slice from 2 cap: %d\n", cap(slice1)) // 8 (10-2)
    
    // Slice from index 2 to 4
    slice2 := original[2:4]
    fmt.Printf("Slice 2:4 cap: %d\n", cap(slice2)) // Still 8
}

Slicing affects capacity based on the starting index. The capacity becomes the original capacity minus the starting index of the slice.

Practical capacity usage

Understanding capacity helps optimize slice operations. This example shows pre-allocation using capacity for performance.

preallocate_slice.go
package main

import (
    "fmt"
    "time"
)

func processWithoutPreallocation(n int) {
    start := time.Now()
    var s []int
    
    for i := 0; i < n; i++ {
        s = append(s, i)
    }
    elapsed := time.Since(start)
    fmt.Printf("Without preallocation: %v\n", elapsed)
}

func processWithPreallocation(n int) {
    start := time.Now()
    s := make([]int, 0, n) // Preallocate capacity
    
    for i := 0; i < n; i++ {
        s = append(s, i)
    }
    elapsed := time.Since(start)
    fmt.Printf("With preallocation: %v\n", elapsed)
}

func main() {
    const size = 1000000
    processWithoutPreallocation(size)
    processWithPreallocation(size)
}

Preallocating capacity avoids repeated allocations during append operations. This significantly improves performance for large slices.

Source

Go language specification

This tutorial covered the cap function in Go with practical examples of capacity usage with arrays and slices.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.