or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

apidiff.mdconstraints.mdebnf.mderrors.mdevent.mdgorelease.mdindex.mdio-i2c.mdio-spi.mdjsonrpc2.mdmaps.mdmmap.mdmodgraphviz.mdrand.mdshiny.mdslices.mdslog.mdstats.mdsumdb.mdtrace.mdtxtar.mdtypeparams.mdutf8string.md
tile.json

slices.mddocs/

golang.org/x/exp/slices

Package slices defines various functions useful with slices of any type. This package provides generic slice operations that work with any element type through Go's type parameters. It includes functions for searching, sorting, comparing, modifying, and querying slices.

Note: This package is largely superseded by Go's built-in slices package (available in Go 1.21+), which contains similar functionality. The experimental package remains available for backward compatibility and for users on older Go versions.

Package Information

  • Package Name: golang.org/x/exp/slices
  • Package Type: Go (golang)
  • Language: Go
  • Installation: go get golang.org/x/exp/slices

Core Imports

import (
    "golang.org/x/exp/slices"
    "cmp"
)

The package uses Go 1.18+ generics. The cmp package is used for comparison functions in generic contexts.

Basic Usage

package main

import (
    "fmt"
    "golang.org/x/exp/slices"
)

func main() {
    // Clone a slice
    original := []int{1, 2, 3, 4, 5}
    cloned := slices.Clone(original)

    // Search in sorted slice
    sorted := []int{1, 3, 5, 7, 9}
    idx, found := slices.BinarySearch(sorted, 5)
    fmt.Println(found) // true

    // Check if slice contains value
    contains := slices.Contains([]string{"a", "b", "c"}, "b")
    fmt.Println(contains) // true

    // Sort a slice
    numbers := []int{5, 2, 8, 1, 9}
    slices.Sort(numbers)
    fmt.Println(numbers) // [1 2 5 8 9]
}

Capabilities

Searching

Functions for searching elements in slices.

BinarySearch

Searches for a target value in a sorted slice using binary search.

func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)

Returns the position where target is found (or would be inserted), and a boolean indicating whether the target was actually found. The slice must be sorted in ascending order.

Example:

sorted := []int{1, 3, 5, 7, 9}
idx, found := slices.BinarySearch(sorted, 5)
// idx = 2, found = true

idx, found = slices.BinarySearch(sorted, 4)
// idx = 2, found = false (4 would be inserted at position 2)

BinarySearchFunc

Like BinarySearch but uses a custom comparison function.

func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)

The comparison function should return 0 if elements match, a negative number if the slice element precedes the target, or a positive number if it follows.

Example:

type Person struct {
    Age int
    Name string
}

people := []Person{{Age: 25, Name: "Alice"}, {Age: 35, Name: "Bob"}}
idx, found := slices.BinarySearchFunc(people, 30, func(p Person, target int) int {
    if p.Age < target {
        return -1
    }
    if p.Age > target {
        return 1
    }
    return 0
})

Sorting

Functions for sorting slices.

Sort

Sorts a slice of any ordered type in ascending order.

func Sort[S ~[]E, E cmp.Ordered](x S)

Modifies the slice in place. NaNs are ordered before other floating-point values.

Example:

numbers := []int{5, 2, 8, 1, 9}
slices.Sort(numbers)
// numbers is now [1 2 5 8 9]

SortFunc

Sorts a slice using a custom comparison function.

func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int)

The comparison function should return a negative number when a < b, a positive number when a > b, and zero when a == b. This sort is not guaranteed to be stable.

Example:

type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Alice", 30},
    {"Bob", 25},
    {"Charlie", 35},
}

slices.SortFunc(people, func(a, b Person) int {
    if a.Age < b.Age {
        return -1
    }
    if a.Age > b.Age {
        return 1
    }
    return 0
})

SortStableFunc

Sorts a slice while keeping the original order of equal elements (stable sort).

func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int)

Behaves like SortFunc but preserves the order of elements that compare equal.

Comparison

Functions for comparing slices and their elements.

Compare

Compares two slices element-by-element using natural ordering.

func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int

Returns 0 if slices are equal, -1 if s1 < s2, and 1 if s1 > s2. If one slice is a prefix of the other, the shorter slice is considered less than the longer one.

Example:

result := slices.Compare([]int{1, 2}, []int{1, 3})
// result = -1 (first slice is less)

result = slices.Compare([]int{1, 2}, []int{1, 2})
// result = 0 (slices are equal)

CompareFunc

Compares two slices using a custom comparison function.

func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int

Similar to Compare but allows comparing slices of different element types.

Equal

Reports whether two slices are equal (same length and all elements equal).

func Equal[S ~[]E, E comparable](s1, s2 S) bool

Returns false if lengths differ. Floating-point NaNs are not considered equal.

Example:

equal := slices.Equal([]int{1, 2, 3}, []int{1, 2, 3})
// equal = true

equal = slices.Equal([]int{1, 2}, []int{1, 2, 3})
// equal = false

EqualFunc

Compares two slices using a custom equality function.

func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool

Returns false if lengths differ or if any elements don't satisfy the equality function.

Searching for Elements

Functions for finding elements in slices.

Contains

Reports whether a value is present in the slice.

func Contains[S ~[]E, E comparable](s S, v E) bool

Returns true if the value is found, false otherwise.

Example:

contains := slices.Contains([]string{"apple", "banana", "orange"}, "banana")
// contains = true

ContainsFunc

Reports whether at least one element satisfies a predicate function.

func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool

Example:

hasEven := slices.ContainsFunc([]int{1, 3, 5, 7, 8}, func(v int) bool {
    return v%2 == 0
})
// hasEven = true

Index

Returns the index of the first occurrence of a value, or -1 if not found.

func Index[S ~[]E, E comparable](s S, v E) int

Example:

idx := slices.Index([]int{10, 20, 30, 20, 40}, 20)
// idx = 1 (first occurrence)

idx = slices.Index([]int{10, 20, 30}, 50)
// idx = -1 (not found)

IndexFunc

Returns the first index where a predicate function returns true, or -1 if none do.

func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int

Example:

idx := slices.IndexFunc([]int{2, 4, 6, 7, 8}, func(v int) bool {
    return v%2 == 1
})
// idx = 3 (7 is odd)

Modifying Slices

Functions for modifying slice contents.

Clone

Returns a shallow copy of the slice.

func Clone[S ~[]E, E any](s S) S

Elements are copied by assignment. The capacity of the clone is equal to its length.

Example:

original := []int{1, 2, 3, 4, 5}
cloned := slices.Clone(original)
cloned[0] = 999
// original[0] is still 1

Clip

Removes unused capacity from the slice, returning s[:len(s):len(s)].

func Clip[S ~[]E, E any](s S) S

Reduces the slice's capacity to match its length. Useful for releasing excess allocated memory.

Example:

s := make([]int, 3, 10) // length 3, capacity 10
s = slices.Clip(s)
// Now length and capacity are both 3

Delete

Removes elements from the slice, returning the modified slice.

func Delete[S ~[]E, E any](s S, i, j int) S

Removes elements from index i to j (s[i:j]). Elements at s[i:] are shifted up. Panics if j > len(s) or if s[i:j] is invalid. Zeroes elements s[len(s)-(j-i):len(s)].

Example:

s := []int{1, 2, 3, 4, 5}
s = slices.Delete(s, 1, 3) // Remove indices 1 and 2
// s is now [1 4 5]

DeleteFunc

Removes all elements for which a function returns true.

func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S

Returns the modified slice. Zeroes elements between the new length and original length.

Example:

s := []int{1, 2, 3, 4, 5, 6}
s = slices.DeleteFunc(s, func(v int) bool {
    return v%2 == 0 // Remove even numbers
})
// s is now [1 3 5]

Insert

Inserts values into the slice at a specified index.

func Insert[S ~[]E, E any](s S, i int, v ...E) S

Elements at s[i:] are shifted up to make room. In the returned slice r, r[i] == v[0]. Panics if i is out of range. This is O(len(s) + len(v)).

Example:

s := []int{1, 2, 5}
s = slices.Insert(s, 2, 3, 4)
// s is now [1 2 3 4 5]

Replace

Replaces elements from index i to j with new values.

func Replace[S ~[]E, E any](s S, i, j int, v ...E) S

Replaces s[i:j] with the given values. Panics if s[i:j] is invalid. If len(v) < (j-i), zeroes elements between the new and original lengths.

Example:

s := []int{1, 2, 3, 4, 5}
s = slices.Replace(s, 1, 4, 20, 30)
// s is now [1 20 30 5]

Reverse

Reverses the elements of the slice in place.

func Reverse[S ~[]E, E any](s S)

Example:

s := []int{1, 2, 3, 4, 5}
slices.Reverse(s)
// s is now [5 4 3 2 1]

Compact

Replaces consecutive runs of equal elements with a single copy.

func Compact[S ~[]E, E comparable](s S) S

Like the Unix uniq command. Modifies the slice and returns it with potentially smaller length. Zeroes elements between new and original lengths.

Example:

s := []int{1, 1, 2, 2, 2, 3, 3, 4}
s = slices.Compact(s)
// s is now [1 2 3 4]

CompactFunc

Like Compact but uses a custom equality function.

func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S

Keeps the first element of each run of equal elements.

Example:

type Person struct {
    Name string
    ID   int
}

s := []Person{
    {"Alice", 1}, {"Alice", 1},
    {"Bob", 2}, {"Bob", 2}, {"Bob", 2},
}

s = slices.CompactFunc(s, func(a, b Person) bool {
    return a.ID == b.ID
})
// s now has only 2 elements (one Alice, one Bob)

Min/Max

Functions for finding minimum and maximum values.

Max

Returns the maximal value in the slice.

func Max[S ~[]E, E cmp.Ordered](x S) E

Panics if the slice is empty. For floating-point numbers, propagates NaNs (any NaN forces the output to be NaN).

Example:

max := slices.Max([]int{3, 1, 4, 1, 5, 9, 2, 6})
// max = 9

MaxFunc

Returns the maximal value using a custom comparison function.

func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E

Panics if the slice is empty. If multiple elements are maximal, returns the first one.

Min

Returns the minimal value in the slice.

func Min[S ~[]E, E cmp.Ordered](x S) E

Panics if the slice is empty. For floating-point numbers, propagates NaNs.

Example:

min := slices.Min([]int{3, 1, 4, 1, 5, 9, 2, 6})
// min = 1

MinFunc

Returns the minimal value using a custom comparison function.

func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E

Panics if the slice is empty. If multiple elements are minimal, returns the first one.

Capacity Management

Functions for managing slice capacity.

Grow

Increases the slice's capacity to guarantee space for more elements.

func Grow[S ~[]E, E any](s S, n int) S

After Grow(n), at least n elements can be appended to the slice without another allocation. Panics if n is negative or too large to allocate memory.

Example:

s := []int{1, 2, 3}
s = slices.Grow(s, 5)
// Now at least 5 more elements can be appended without reallocation
s = append(s, 4, 5, 6, 7, 8)

Sorting Status

Functions for checking if slices are sorted.

IsSorted

Reports whether a slice is sorted in ascending order.

func IsSorted[S ~[]E, E cmp.Ordered](x S) bool

Example:

sorted := slices.IsSorted([]int{1, 2, 3, 4, 5})
// sorted = true

sorted = slices.IsSorted([]int{1, 3, 2, 4, 5})
// sorted = false

IsSortedFunc

Reports whether a slice is sorted using a custom comparison function.

func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool

Type Constraints

The package uses Go 1.18+ generic constraints:

// Constraints from cmp package used by this package
type Ordered interface {
    ~int | ~int8 | ~int16 | ~int32 | ~int64 |
    ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
    ~float32 | ~float64 |
    ~string
}
  • S ~[]E - Slice type constraint (S is a type with underlying type []E)
  • E cmp.Ordered - Ordered types (integers, floats, strings)
  • E comparable - Comparable types (can be compared with ==)
  • E any - Any type (used with custom comparison functions)

Important Notes

  1. Generics Requirement: Requires Go 1.18 or later for full support.

  2. In-Place Modifications: Many functions (Sort, Reverse, Delete, etc.) modify the slice in place. However, they may return a different slice header due to the way Go handles slice resizing.

  3. Panics: Some functions panic on invalid input:

    • Search and min/max functions panic on empty slices
    • Delete and Replace panic if indices are out of range
    • Grow panics if n is negative or causes allocation failure
  4. Memory Cleanup: Functions like Compact, Delete, and DeleteFunc zero out elements between the new length and original length to allow garbage collection.

  5. Stability: SortFunc is not stable, but SortStableFunc maintains the original order of equal elements.

  6. NaN Handling: Max and Min propagate NaNs in floating-point slices. Sort places NaNs before other values.

  7. Comparison Functions: When using custom comparison functions, they must implement strict weak ordering. Return -1 for a < b, 0 for a == b or uncomparable, and 1 for a > b.

Superseded By Built-in Package

As of Go 1.21, the built-in slices package provides equivalent functionality without requiring external dependencies. For new projects using Go 1.21+, prefer using the built-in slices package from the standard library.