В версии Go 1.21, был добавлен новый пакет под названием slices
. Этот пакет представляет собой набор функций, которые облегчают выполнение наиболее распространенных операций со слайсами. Пакет появился благодаря добавлению дженериков ранее в 1.18. Все функции в пакете являются обобщенными (или "generics").
Что такое generics?
Generics - это функции или типы, которые могут работать с любым типом данных. В Go generics были введены в версии 1.18 и они означают, что вы можете написать функцию, которая будет работать с любым типом данных, а не только с определенным.
Например, функция Delete
из пакета slices
выглядит так:
func Delete[S ~[]E, E any](s S, i, j int) S
Здесь S
и E
- это параметры типа. S
представляет тип слайса, а E
- тип элементов в этом слайсе. Тильда (~
) означает, что S
может быть любым типом, который может быть приведен к этому слайсу.
Например, если у вас есть следующие типы:
type MyType int
type MySlice []MyType
Вы можете использовать функции из пакета slices
с объектами типа MySlice
.
Функции пакета slices
Большая часть функций пакета имеет версии с приставкой Func
, которые позволяют использовать свои функции. Это дает большую гибкость при работе со слайсами.
Например, функции Sort
, IsSorted
, Min
, Max
и BinarySearch
могут быть применены к слайсам, элементы которых реализуют интерфейс Ordered
. Этот интерфейс включает в себя все базовые числовые типы и строки, и типы которые могут быть приведены к ним.
type Ordered interface {
~int | ~int8 | ~int16 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
~string
}
Для слайсов других типов, вы можете использовать варианты этих функций с суффиксом Func
и предоставить свою функцию сравнения, которая принимает два элемента и возвращает bool.
Equal
и EqualFunc
проверяют равенство двух срезов, сравнивая элементы напрямую или используя пользовательскую функцию равенства.
Compare
и CompareFunc
сравнивают два среза последовательно и возвращают <0, 0 или >0 в зависимости от того, меньше, равен или больше первый неравный элемент в s1 по отношению к соответствующему элементу в s2.
Index
и IndexFunc
возвращают индекс первого элемента, удовлетворяющего предикату, или -1, если ни один элемент не удовлетворяет.
Contains
и ContainsFunc
проверяют, соответствует ли значение или предикат любому элементу.
Insert
эффективно O(len(s) + len(v))
вставляет элементы в срез на заданном индексе, расширяя срез при необходимости.
Delete
и DeleteFunc
удаляют элементы из среза по индексу или предикату.
Replace
заменяет срез элементов на новые значения.
Особенности
Функция удаления Delete
, в пакете, достаточно простая:
func Delete[S ~[]E, E any](s S, i, j int) S {
_ = s[i:j] // bounds check
return append(s[:i], s[j:]...)
}
Такой подход имеет недостаток. После удаления объекты могут оставаться в исходном массиве, и garbage collector не удалить их из памяти. Также новый slice будет иметь capacity равный исходному слайсу.
Функция Clip
, уменьшает capacity слайса до его текущей длины.
func Clip[S ~[]E, E any](s S) S {
return s[:len(s):len(s)]
}
Такой функционал для слайсов появился в Go начиная с версии 1.2 когда ввели Full slice expression.
Full slice expression a[low : high : max]
Simple slice expression a[low : high]
Комментарии (6)
dsbasko
22.10.2023 10:22+1В тексте ошибка.
Generics - это функции или типы, которые могут работать с любым типом данных. В Go generics были введены в версии 1.21 и они означают, что вы можете написать функцию, которая будет работать с любым типом данных, а не только с определенным.
Введены они были в 1.18
tushev
Как то не много полезных плюшек в этом пакете. Пожалуй, пока продолжу использовать https://github.com/samber/lo Там и слайсы и мапы и прочие полезности, нужные в повседневной работе.
Razzer Автор
Да, пакет бедный. Но он в стандарте. И можно использовать, почти в любом проекте. Странно что так долго тянули с ним, могли бы сразу в 1.18 добавлять.
Katenk_aa
дайте ссылочку на гид пж
Razzer Автор
Возможно, не совсем понял правильно вопрос.
Для использования пакета slices ничего ставить не надо.
Просто указать
и запускать от версии 1.21+ для go
ссылка https://github.com/golang/go/tree/master/src/slices