Detailed explanation of the new slices package in Go 1.21 (1)

The new slices package in Go 1.21 provides many slice-related functions that can be used for any type of slice.

slices.BinarySearch

The definition is as follows:

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

Search for the target in the sorted slices (the slices must be sorted in increasing order). If found, return the location and true. If not found, return the location where the target should be found and false. A simple example is as follows:

package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	n, found := slices.BinarySearch(names, "Vera")
	fmt.Println("Vera:", n, found) // Vera: 2 true

	n, found = slices.BinarySearch(names, "Bill")
	fmt.Println("Bill:", n, found) // Bill: 1 false
}

slices.BinarySearchFunc

The definition is as follows:

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

It works like slices.BinarySearch, except that it uses a custom comparison function. Slices must be sorted in increasing order, where "increasing" is defined by cmp. CMP should return 0 if the slice element matches the target, a negative number if the slice element precedes the target, and a positive number if the slice element follows the target. CMP must implement the same ordering as slices, such that if CMP (a, t) < 0 and CMP (b, t) >= 0, the sliced ​​a must come before b.

package main

import (
	"cmp"
	"fmt"
	"slices"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	people := []Person{
		{"Alice", 55},
		{"Bob", 24},
		{"Gopher", 13},
	}
	n, found := slices.BinarySearchFunc(people, Person{"Bob", 0}, func(a, b Person) int {
		return cmp.Compare(a.Name, b.Name)
	})
	fmt.Println("Bob:", n, found) // Bob: 1 true
}

slices.Clip

The definition is as follows:

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

Removes unused capacity from the slice, returning s[:len(s):len(s)]. A simple example is as follows:

package main

import (
	"fmt"
	"slices"
)

func main() {
	names := make([]string, 2, 5)
	names = slices.Clip(names)
	fmt.Printf("长度:%d,容量:%d", len(names), cap(names))
  // 长度:2,容量:2
}

slices.Clone

The definition is as follows:

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

Returns a copy of the slice. Because the elements are copied using assignment, this is a shallow clone. Simple and practical methods are as follows:

package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"路多辛的博客", "路多辛的所思所想"}
	namesCopy := slices.Clone(names)
	fmt.Println(namesCopy)
}

slices.Compact

The definition is as follows:

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

Turn consecutive elements into one, similar to the uniq command on Unix. Compact modifies the contents of the slice and returns the modified slice, possibly smaller in length. A simple example is as follows:

package main

import (
	"fmt"
	"slices"
)

func main() {
	seq := []int{0, 1, 1, 2, 5, 5, 5, 8}
	seq = slices.Compact(seq)
	fmt.Println(seq) // [0 1 2 5 8]
}

slices.CompactFunc

The definition is as follows:

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

Similar to slices.Compact, except that a custom function is used to compare elements. If the elements run equal, CompactFunc retains the first element. A simple example is as follows:

package main

import (
	"fmt"
	"slices"
	"strings"
)

func main() {
	names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
	names = slices.CompactFunc(names, func(a, b string) bool {
		return strings.ToLower(a) == strings.ToLower(b)
	})
	fmt.Println(names) // [bob alice Vera]
}

slices.Compare

The definition is as follows:

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

Use the cmp.Compare function to compare the elements of s1 and s2. Each pair of elements is compared sequentially until one element is not equal to the other. Returns the result for the first unmatched element. If two slices are equal before one of them ends, the shorter slice is considered smaller than the longer slice. If s1 == s2, the result is 0; if s1 < s2, the result is -1; if s1 > s2, the result is 1.

package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	fmt.Println("Equal:", slices.Compare(names, []string{"Alice", "Bob", "Vera"}))
	fmt.Println("V < X:", slices.Compare(names, []string{"Alice", "Bob", "Xena"}))
	fmt.Println("V > C:", slices.Compare(names, []string{"Alice", "Bob", "Cat"}))
	fmt.Println("3 > 2:", slices.Compare(names, []string{"Alice", "Bob"}))
}

The running results are as follows:

Equal: 0
V < X: -1
V > C: 1
3 > 2: 1

slices.CompareFunc

The definition is as follows:

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

Similar to slices.Compare, except that a custom comparison function is used for comparison. The result is the first non-zero result of cmp; if cmp always returns 0, the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2) len(s1) > len(s2) results in 1. A simple example is as follows:

package main

import (
	"cmp"
	"fmt"
	"slices"
	"strconv"
)

func main() {
	numbers := []int{0, 43, 8}
	strings := []string{"0", "0", "8"}
	result := slices.CompareFunc(numbers, strings, func(n int, s string) int {
		sn, err := strconv.Atoi(s)
		if err != nil {
			return 1
		}
		return cmp.Compare(n, sn)
	})
	fmt.Println(result) // 1
}

slices.Contains

The definition is as follows:

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

Used to determine whether s contains v. A simple example is as follows:

package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	fmt.Println(slices.Contains(names, "Bob")) // true
}

slices.ContainsFunc

The definition is as follows:

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

Used to determine whether at least one element e in s satisfies f(e). A simple example is as follows:

package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, -10, 8}
	hasNegative := slices.ContainsFunc(numbers, func(n int) bool {
		return n < 0
	})
	fmt.Println("Has a negative:", hasNegative)// true
	hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
		return n%2 != 0
	})
	fmt.Println("Has an odd number:", hasOdd) // false
}

【Reference】

Package slices(https://golang.google.cn/pkg/slices/)

Guess you like

Origin blog.csdn.net/luduoyuan/article/details/132330420