immutable

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: LGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package immutable holds value types that keep their storage private, so nothing outside this package can reach into one. A value is built once, read freely, and replaced as a whole when something new is needed. That encapsulation is what lets a component hold one without handing the world's backing memory to every caller of Get.

The name describes the intended discipline rather than a guarantee the compiler enforces. Slice derivations edit in place by review decision, so read Slice's own doc before using one.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BinarySearch

func BinarySearch[T cmp.Ordered](s Slice[T], target T) (int, bool)

BinarySearch searches a sorted s for target and returns the position where it is, or would be inserted, and whether it was found, like slices.BinarySearch.

func BinarySearchFunc

func BinarySearchFunc[E, T any](s Slice[E], target T, compare func(E, T) int) (int, bool)

BinarySearchFunc is BinarySearch with a comparison function, whose target may be of another type, like slices.BinarySearchFunc.

func Compare

func Compare[T cmp.Ordered](a, b Slice[T]) int

Compare compares a and b element by element, like slices.Compare.

func CompareFunc

func CompareFunc[E1, E2 any](a Slice[E1], b Slice[E2], compare func(E1, E2) int) int

CompareFunc is Compare with a comparison function, whose Slices may hold different element types, like slices.CompareFunc.

func Contains

func Contains[T comparable](s Slice[T], v T) bool

Contains reports whether v is an element of s.

func Equal

func Equal[T comparable](a, b Slice[T]) bool

Equal reports whether a and b hold the same elements in the same order. It is a function rather than a method because a method cannot narrow T to comparable; use EqualFunc for other element types.

func Index

func Index[T comparable](s Slice[T], v T) int

Index returns the index of the first element of s equal to v, or -1.

func IsSorted

func IsSorted[T cmp.Ordered](s Slice[T]) bool

IsSorted reports whether the elements of s are in ascending order.

func Max

func Max[T cmp.Ordered](s Slice[T]) T

Max returns the largest element of s. It panics when s is empty, like slices.Max.

func Min

func Min[T cmp.Ordered](s Slice[T]) T

Min returns the smallest element of s. It panics when s is empty, like slices.Min.

func SliceElem

func SliceElem(t reflect.Type) (reflect.Type, bool)

SliceElem reports whether t is an instantiation of Slice and, if so, returns its element type. It exists so tooling that works through reflection, such as the DST random filler, can recognise a Slice without depending on how it is laid out.

Types

type Slice

type Slice[T any] struct {
	// contains filtered or unexported fields
}

Slice is a sequence with a private backing array, for component fields whose length is genuinely unbounded. It is the only variable-length collection a component may hold.

A component column stores values and Get hands back a copy, but a raw []T inside that copy still shares its backing array with the column. Slice keeps that array unexported, so no caller can index into it, reslice it, or pass it to another package, and Get stays zero-copy.

What Slice does not do is copy on a derivation. Most derivations edit the backing array in place and return a Slice over that same array, so the column has already changed by the time the derivation returns. Always Set the component afterwards:

inv := ref.Get()
inv.Items = inv.Items.With(0, item) // the column's array has changed here
ref.Set(inv)                        // this republishes what is already true

Deriving and dropping the result does not leave the world untouched — it leaves the world holding an edit no snapshot recorded. Copy the elements out first (Values, or immutable.Collect) when the original has to survive. Each derivation's doc says whether it writes through.

Two empty Slices are not always reflect.DeepEqual. A derivation that empties one leaves its backing array allocated, while the zero value and SliceOf have none, and DeepEqual looks at the field rather than the elements. Compare with Equal or EqualFunc, which compare elements and agree with slices.Equal that nil and empty are the same list. The generated decoder leaves an empty repeated field as the zero value, so a component restored from a snapshot does match one built fresh.

The element type must be value-safe too: scalars, strings, fixed arrays, or structs of those. Slice does not check this — Slice[*T] compiles, and hands the pointer straight back out of At — but the wire generator refuses such an element, and refuses a Slice directly inside a Slice, which protobuf cannot carry (wrap the inner one in a named struct).

func Collect

func Collect[T any](seq iter.Seq[T]) Slice[T]

Collect returns a Slice holding every element of seq, in order.

func Compact

func Compact[T comparable](s Slice[T]) Slice[T]

Compact returns a Slice with runs of consecutive equal elements collapsed to one, like slices.Compact. Like CompactFunc it writes through, so s keeps its old length over the shifted, zero-filled tail.

NOTE: Requires component set if used.

func Concat

func Concat[T any](ss ...Slice[T]) Slice[T]

Concat returns a new Slice holding the elements of every argument, in order.

func Map

func Map[T, U any](s Slice[T], f func(T) U) Slice[U]

Map returns a new Slice holding f applied to each element of s, in order.

func SliceOf

func SliceOf[T any](items ...T) Slice[T]

SliceOf returns a Slice holding a copy of items. Later changes to the caller's slice do not reach the returned value.

func Sorted

func Sorted[T cmp.Ordered](s Slice[T]) Slice[T]

Sorted returns a Slice with the elements of s in ascending order. The sort is stable. Like SortedFunc it writes through, so s ends up sorted too.

NOTE: Requires component set if used.

func (Slice[T]) All

func (s Slice[T]) All() iter.Seq2[int, T]

All returns an iterator over index and element, in order. Elements are yielded by value.

func (Slice[T]) Append

func (s Slice[T]) Append(items ...T) Slice[T]

Append returns a Slice with items added at the end. It allocates a new array, so the receiver is unchanged.

NOTE: Requires component set if used.

func (Slice[T]) At

func (s Slice[T]) At(i int) T

At returns a copy of the element at index i. It panics when i is out of range, like a slice.

func (Slice[T]) Backward

func (s Slice[T]) Backward() iter.Seq2[int, T]

Backward returns an iterator over index and element from the last element to the first.

func (Slice[T]) Chunk

func (s Slice[T]) Chunk(n int) iter.Seq[Slice[T]]

Chunk returns an iterator over consecutive sub-Slices of up to n elements. It panics when n is less than one, like slices.Chunk.

NOTE: Requires component set if used.

func (Slice[T]) CompactFunc

func (s Slice[T]) CompactFunc(eq func(a, b T) bool) Slice[T]

CompactFunc returns a Slice with runs of consecutive elements that eq reports equal collapsed to one, like slices.CompactFunc. It writes through: the receiver keeps its old length over the shifted, zero-filled tail.

NOTE: Requires component set if used.

func (Slice[T]) ContainsFunc

func (s Slice[T]) ContainsFunc(f func(T) bool) bool

ContainsFunc reports whether f is true for any element.

func (Slice[T]) Delete

func (s Slice[T]) Delete(i, j int) Slice[T]

Delete returns a Slice with the elements in [i, j) removed. It writes through: the receiver keeps its old length over the shifted, zero-filled tail. It panics when the range is out of bounds, like slices.Delete.

NOTE: Requires component set if used.

func (Slice[T]) EqualFunc

func (s Slice[T]) EqualFunc(other Slice[T], eq func(a, b T) bool) bool

EqualFunc reports whether both slices have the same length and eq holds for every pair of elements at the same index.

func (Slice[T]) Filter

func (s Slice[T]) Filter(keep func(T) bool) Slice[T]

Filter returns a Slice holding the elements for which keep is true, in order, and keep runs once per element. It writes through: the receiver keeps its old length over the shifted, zero-filled tail.

NOTE: Requires component set if used.

func (Slice[T]) IndexFunc

func (s Slice[T]) IndexFunc(f func(T) bool) int

IndexFunc returns the index of the first element for which f is true, or -1.

func (Slice[T]) Insert

func (s Slice[T]) Insert(i int, items ...T) Slice[T]

Insert returns a Slice with items inserted at index i, which may equal Len. It writes through whenever the receiver has the spare capacity to hold the result and allocates otherwise, so treat the receiver as changed either way. It panics when i is out of range, like slices.Insert.

NOTE: Requires component set if used.

func (Slice[T]) IsSortedFunc

func (s Slice[T]) IsSortedFunc(compare func(a, b T) int) bool

IsSortedFunc reports whether the elements are in ascending order according to compare.

func (Slice[T]) Len

func (s Slice[T]) Len() int

Len returns the number of elements.

func (Slice[T]) MarshalJSON added in v0.16.8

func (s Slice[T]) MarshalJSON() ([]byte, error)

MarshalJSON encodes the Slice as a JSON array of its items. The zero value encodes as `[]`, not `null`: a Slice is never "absent", only empty.

func (Slice[T]) MaxFunc

func (s Slice[T]) MaxFunc(compare func(a, b T) int) T

MaxFunc returns the maximal element according to compare. It panics when the Slice is empty, like slices.MaxFunc.

func (Slice[T]) MinFunc

func (s Slice[T]) MinFunc(compare func(a, b T) int) T

MinFunc returns the minimal element according to compare. It panics when the Slice is empty, like slices.MinFunc.

func (Slice[T]) Repeat

func (s Slice[T]) Repeat(count int) Slice[T]

Repeat returns a Slice holding the elements count times over. It allocates a new array, so the receiver is unchanged. It panics when count is negative or the result would overflow, like slices.Repeat.

NOTE: Requires component set if used.

func (Slice[T]) Replace

func (s Slice[T]) Replace(i, j int, items ...T) Slice[T]

Replace returns a Slice with the elements in [i, j) replaced by items. It writes through whenever the receiver has the spare capacity to hold the result and allocates otherwise, so treat the receiver as changed either way. It panics when the range is out of bounds, like slices.Replace.

NOTE: Requires component set if used.

func (Slice[T]) Reversed

func (s Slice[T]) Reversed() Slice[T]

Reversed returns a Slice with the elements in reverse order. It writes through: the receiver is reversed too, so calling it once a tick in a query flips the stored order every tick. To read in reverse without deriving anything, use Backward.

NOTE: Requires component set if used.

func (Slice[T]) SortedFunc

func (s Slice[T]) SortedFunc(compare func(a, b T) int) Slice[T]

SortedFunc returns a Slice sorted by compare, which reports a<b as negative, a==b as zero and a>b as positive. The sort is stable, so equal elements keep their order. It writes through: the receiver is sorted too, so even a read-only use such as s.SortedFunc(cmp).At(0) reorders the column. To find one extreme without deriving anything, use MinFunc or MaxFunc.

NOTE: Requires component set if used.

func (Slice[T]) Sub

func (s Slice[T]) Sub(lo, hi int) Slice[T]

Sub returns a Slice holding the elements in [lo, hi). It is the one derivation that writes nothing, but the result is a window onto the receiver's array, so deriving from that window writes into the receiver. It panics when the range is out of bounds, like s[lo:hi].

The bounds are checked against Len explicitly: a derived Slice can have spare capacity, and a plain slice expression would read past the end into it.

NOTE: Requires component set if used.

func (*Slice[T]) UnmarshalJSON added in v0.16.8

func (s *Slice[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON replaces the Slice with the array in data. An empty array and `null` both yield the zero value — nil items, not an empty allocation — so a decoded empty Slice compares equal to a fresh one under reflect.DeepEqual, the same rule the generated FromProto follows.

func (Slice[T]) Values

func (s Slice[T]) Values() iter.Seq[T]

Values returns an iterator over the elements, in order. Elements are yielded by value.

func (Slice[T]) With

func (s Slice[T]) With(i int, v T) Slice[T]

With returns a Slice with the element at index i replaced by v. It writes through: the receiver holds v at i as well. It panics when i is out of range, like a slice.

NOTE: Requires component set if used.

func (Slice[T]) Without

func (s Slice[T]) Without(i int) Slice[T]

Without returns a Slice with the element at index i removed. It writes through: the receiver keeps its old length over the shifted, zero-filled tail. It panics when i is out of range, like a slice.

NOTE: Requires component set if used.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL