Golang slices.Clip
last modified April 20, 2025
This tutorial explains how to use the slices.Clip
function in Go.
We'll cover slice operations with practical examples of memory optimization.
The slices.Clip function removes unused capacity from a slice, returning a new slice with length equal to capacity. It's part of Go's slices package.
This function is useful for memory optimization when you want to reduce the underlying array size to exactly fit the slice's elements.
Basic slices.Clip Example
The simplest use of slices.Clip
demonstrates how it reduces a
slice's capacity to match its length. We'll create a slice with extra capacity.
package main import ( "fmt" "slices" ) func main() { s := make([]int, 3, 10) // length 3, capacity 10 fmt.Printf("Before: len=%d, cap=%d\n", len(s), cap(s)) clipped := slices.Clip(s) fmt.Printf("After: len=%d, cap=%d\n", len(clipped), cap(clipped)) }
We create a slice with length 3 and capacity 10. After clipping, the capacity matches the length. The original slice remains unchanged.
Clip After Append Operations
slices.Clip
is often used after append operations that may leave
extra capacity. This example shows clipping after growing a slice.
package main import ( "fmt" "slices" ) func main() { s := []int{1, 2, 3} s = append(s, 4, 5) fmt.Printf("After append: len=%d, cap=%d\n", len(s), cap(s)) s = slices.Clip(s) fmt.Printf("After clip: len=%d, cap=%d\n", len(s), cap(s)) }
Appending elements often increases capacity beyond what's needed. Clipping ensures the slice uses only necessary memory.
Clip with Sub-slices
Clipping works with sub-slices created through slicing operations. This example shows clipping a sub-slice of a larger slice.
package main import ( "fmt" "slices" ) func main() { original := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} sub := original[2:5] // len=3, cap=8 fmt.Printf("Sub-slice before: len=%d, cap=%d\n", len(sub), cap(sub)) clipped := slices.Clip(sub) fmt.Printf("Sub-slice after: len=%d, cap=%d\n", len(clipped), cap(clipped)) }
The sub-slice initially has capacity extending to the end of the original array. Clipping removes this unused capacity.
Clip with Empty Slices
slices.Clip
handles empty slices specially. This example shows its
behavior with nil and empty slices.
package main import ( "fmt" "slices" ) func main() { var nilSlice []int emptySlice := []int{} fmt.Println("Nil slice before:", len(nilSlice), cap(nilSlice)) clippedNil := slices.Clip(nilSlice) fmt.Println("Nil slice after:", len(clippedNil), cap(clippedNil)) fmt.Println("Empty slice before:", len(emptySlice), cap(emptySlice)) clippedEmpty := slices.Clip(emptySlice) fmt.Println("Empty slice after:", len(clippedEmpty), cap(clippedEmpty)) }
Clipping a nil slice returns nil. Clipping an empty non-nil slice returns an empty slice with zero capacity.
Clip for Memory Optimization
This example demonstrates memory savings by clipping large slices that won't grow further.
package main import ( "fmt" "slices" "runtime" ) func printMemUsage() { var m runtime.MemStats runtime.ReadMemStats(&m) fmt.Printf("Alloc = %v MiB\n", m.Alloc/1024/1024) } func main() { printMemUsage() large := make([]int, 1_000_000, 2_000_000) printMemUsage() clipped := slices.Clip(large) printMemUsage() _ = clipped // prevent optimization removal }
The example shows memory allocation before and after clipping. The clipped slice uses half the memory of the original.
Clip with String Slices
slices.Clip
works with slices of any type, including strings. This
example clips a slice of string values.
package main import ( "fmt" "slices" ) func main() { names := make([]string, 3, 10) names[0] = "Alice" names[1] = "Bob" names[2] = "Charlie" fmt.Printf("Before: len=%d, cap=%d\n", len(names), cap(names)) names = slices.Clip(names) fmt.Printf("After: len=%d, cap=%d\n", len(names), cap(names)) }
String slices behave like other types when clipped. The capacity reduces to match the length, optimizing memory usage.
Practical Example: Returning Slices from Functions
This practical example shows clipping slices returned from functions to ensure callers get optimally sized slices.
package main import ( "fmt" "slices" ) func generateNumbers(count int) []int { numbers := make([]int, 0, count*2) // Extra capacity for i := 0; i < count; i++ { numbers = append(numbers, i*10) } return slices.Clip(numbers) } func main() { nums := generateNumbers(5) fmt.Println("Numbers:", nums) fmt.Printf("Length: %d, Capacity: %d\n", len(nums), cap(nums)) }
The function creates a slice with extra capacity during generation but clips it before returning. This provides memory efficiency to callers.
Source
Go experimental slices package documentation
This tutorial covered the slices.Clip
function in Go with practical
examples of memory optimization and slice capacity management.
Author
List all Go tutorials.