https://github.com/jabolopes/go-safeslice
Go slice that can be modified while being traversed.
https://github.com/jabolopes/go-safeslice
data-structures generics go go-library golang golang-library slices utility
Last synced: about 2 months ago
JSON representation
Go slice that can be modified while being traversed.
- Host: GitHub
- URL: https://github.com/jabolopes/go-safeslice
- Owner: jabolopes
- License: bsd-3-clause
- Created: 2022-03-22T20:17:26.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-08-20T22:40:04.000Z (about 3 years ago)
- Last Synced: 2025-02-07T19:49:26.461Z (8 months ago)
- Topics: data-structures, generics, go, go-library, golang, golang-library, slices, utility
- Language: Go
- Homepage:
- Size: 9.77 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# go-safeslice
[](https://pkg.go.dev/github.com/jabolopes/go-safeslice)
SafeSlice is similar to a slice except it is safe for modification during
range-based traversals.This is achieved by guaranteeing that there are no changes made to allocations
of slices returned by previous calls to `Get`. That is, only new calls to `Get`
will observe the elements added, removed, or swapped, to the array before that
call to `Get`.IMPORTANT: See the following examples for safe iteration.
## Installation
```sh
$ go get github.com/jabolopes/go-safeslice
```You can use `go get -u` to update the package. If you are using Go modules, you
can also just import the package and it will be automatically downloaded on the
first compilation.## Examples
The Go language guarantees that the expression passed to `range` is evaluated
only once. Therefore, the following iteration makes a single call to `Get`
before the iteration begins. As such, the slice being traversed does not observe
the added / removed / swapped elements.```go
a := NewSafeSlice()
for _, x := range a.Get() {
a.Append(...) // SAFE
}a := NewSafeSlice()
for _, x := range a.Get() {
a.Remove(0) // SAFE
}
```The following while loop calls `Get` multiple times, therefore the
length of the array is varying between the loops. While this is
correct, it's extremely inefficient because this is forcing a
"snapshot" of the array on each call to the pair (`Get`, `Remove`), so
don't do this.```go
a := NewSafeSlice()
for len(a.Get()) > 0 {
a.Remove(0) // INEFFICIENT; DON'T DO
}
```The following iteration however is NOT safe because each call to
`Get` observes the removed elements.```go
a := NewSafeSlice()
for i := 0; i < len(a.Get()); i++ {
a.Remove(i) // WRONG and UNSAFE
}
```SafeSlice is not safe for concurrent use but it is safe for
non-concurrent modification during traversal.