Skip to content

Archive

Go

100 articles
Cybersecurity 19 Sep 2026 9 min read

Signal Protocol Is a Cryptographic Layer, Not a Transport Protocol

Signal Protocol Is a Cryptographic Layer, Not a Transport Protocol A Go service can deliver messages over WebSocket, HTTP, WebRTC, MQTT, or a store-and-forward queue without any of those transports providing end-to-end encryption. Transport encryption such as TLS protects a connection between network peers. Signal Protocol addresses a different boundary: message content is encrypted at one endpoint and remains ciphertext until the receiving endpoint processes the corresponding cryptographic session. That distinction determines where Signal Protocol belongs in an application. The relay can authenticate accounts, route envelopes, retain undelivered ciphertext, and enforce quotas, but it should not need the conversation keys required to recover message plaintext.

Go 14 Sep 2026 4 min read

Select Minimum Struct Values with slices.MinFunc in Go

slices.MinFunc selects one element from a slice according to a caller-defined ordering. Unlike sorting, it does not rearrange the input, and unlike a field-specific loop, it makes the comparison rule an explicit part of the operation. Its standard-library signature accepts any element type: func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E The comparison function returns a negative value when a precedes b, a positive value when a follows b, and zero when the two values are equal under the chosen order.

Go 14 Sep 2026 4 min read

Search Sorted Slices with slices.BinarySearch in Go

slices.BinarySearch returns more than a membership result. Its index identifies the earliest matching position when a target exists, and the position where that target belongs when it does not. That dual contract makes the function useful for maintaining sorted data as well as querying it. The standard-library signature accepts ordered element types: func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) The input must already be sorted in increasing order. The function does not sort, copy, or mutate the slice.

Go 14 Sep 2026 5 min read

Reverse Slice Order in Go with slices.Reverse

Reversing a Go slice changes element order without requiring a second slice. The standard library’s slices.Reverse function performs that operation in place, so the slice header keeps referring to the same backing storage while pairs of elements are exchanged from the ends toward the center. That in-place behavior is the main property to account for. A call can affect other slices that share the same backing array, and no returned slice exists to make the mutation visually obvious at the call site.

Go 14 Sep 2026 4 min read

Compact Adjacent Slice Values with slices.CompactFunc in Go

slices.CompactFunc removes repeated values only when equivalent elements are next to each other. That adjacency rule makes it different from set-style deduplication: equal values separated by another element remain separate entries. The function accepts a slice and an equality function: func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S It compacts the slice in place and returns the resulting shorter slice.

Go 13 Sep 2026 5 min read

Reserve Slice Capacity with slices.Grow in Go

A slice can have enough logical elements for the current operation and still lack room for the next append. When the number of upcoming elements is already known, slices.Grow makes that capacity requirement explicit without changing the slice length. The function joined the standard library with the slices package in Go 1.21. Its contract is narrow: given a slice and a non-negative count, it returns a slice with enough capacity to append at least that many additional elements without another allocation.

Go 13 Sep 2026 4 min read

Replace Slice Ranges with slices.Replace in Go

slices.Replace changes a contiguous range of a slice and can make the resulting slice shorter, longer, or the same length. That makes it more than element assignment: the operation combines range removal and insertion while retaining Go slice storage semantics. Its signature accepts any slice element type: func Replace[S ~[]E, E any](s S, i, j int, v ...E) S The half-open range s[i:j] is replaced by the values in v. Since the resulting length can change, the returned slice value is part of the operation’s contract.

Go 13 Sep 2026 4 min read

Repeat Slice Patterns with slices.Repeat in Go

slices.Repeat builds a new slice by concatenating a source slice with itself a specified number of times. The operation is small, but its exact contract matters when code depends on allocation, nil state, or reference-bearing elements. The function belongs to the standard slices package and has this signature: func Repeat[S ~[]E, E any](x S, count int) S The returned slice has both length and capacity equal to len(x) * count. The result is never nil.

Go 13 Sep 2026 4 min read

Remove Slice Ranges with slices.Delete in Go

slices.Delete removes one contiguous range from a slice and shifts the remaining suffix toward the front. The operation modifies the supplied backing storage, so its returned slice header is part of the result rather than an optional convenience. Its signature accepts any slice element type: func Delete[S ~[]E, E any](s S, i, j int) S The half-open interval s[i:j] follows ordinary Go slicing rules. Elements at indices from i through j-1 are removed, while elements before i retain their positions.

Go 13 Sep 2026 4 min read

Remove Adjacent Duplicates with slices.Compact in Go

slices.Compact removes repeated values only when they occur next to each other. That detail makes it different from set-based deduplication: the function collapses equal runs, preserves their order, and modifies the supplied slice storage. The operation fits data that is already grouped by value, including sorted slices and streams that naturally produce repeated adjacent states. It does not search the full slice for every matching value. Compact collapses consecutive runs The generic signature accepts slices whose element type is comparable:

Go 13 Sep 2026 4 min read

Partition Go Slices Lazily with slices.Chunk

Batching a slice often starts as index arithmetic: advance by a fixed width, clamp the final boundary, and pass each sub-slice onward. Go 1.23 added slices.Chunk, which expresses that operation as an iterator while preserving the backing storage of the source slice. Its behavior has one detail that matters beyond syntax: every yielded chunk has its capacity clipped to its length. A caller can modify elements through a chunk, but a plain append cannot grow that chunk into the next region of the source slice.

Go 13 Sep 2026 4 min read

Limit Slice Capacity with slices.Clip in Go

A Go slice can expose more capacity than its current length. slices.Clip removes that spare capacity from the slice header, setting capacity to length without copying the elements into new storage. The operation is deliberately narrow. It changes the range that a later append can reuse through that slice value, but it does not release the backing array or create an independent copy. Clip is a full slice expression The standard library defines Clip with this signature:

Go 13 Sep 2026 5 min read

Insert Slice Values with slices.Insert in Go

slices.Insert places one or more values at a specific slice index and shifts the existing suffix to make room. The operation modifies slice storage when possible, but it can also return a slice backed by a new array when existing capacity cannot hold the expanded result. Its generic signature is: func Insert[S ~[]E, E any](s S, i int, v ...E) S The returned slice must replace the previous slice value because insertion changes the length and can change the backing array.

Go 13 Sep 2026 4 min read

Grow Slice Capacity with slices.Grow in Go

slices.Grow reserves room for future appends without changing a slice’s length. The distinction between length and capacity is central to its contract: existing elements remain the logical contents, while the returned slice can accept at least a requested number of additional elements without another allocation. The generic signature is: func Grow[S ~[]E, E any](s S, n int) S The return value matters because increasing capacity can require a new backing array.

Go 13 Sep 2026 3 min read

Find the First Predicate Match with slices.IndexFunc in Go

slices.IndexFunc scans a slice from the beginning and returns the index of the first element accepted by a predicate. That contract is narrower than filtering: only one position is requested, and the scan has no reason to continue after a match. Its standard-library signature accepts any slice element type: func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int The predicate receives each element in index order. A true result ends the search and produces that index. If every call returns false, the function returns -1.

Go 13 Sep 2026 4 min read

Filter Slice Values with slices.DeleteFunc in Go

slices.DeleteFunc removes elements selected by a predicate and compacts the retained values into the same slice storage. It is a filtering operation with mutation semantics: retained order stays intact, the returned slice can be shorter, and callers must use that returned slice header. The generic signature accepts any slice element type: func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S The predicate describes deletion rather than retention. An element disappears when del returns true.

Go 13 Sep 2026 4 min read

Filter a Slice In Place with slices.DeleteFunc in Go

Filtering a Go slice often starts as a small loop that keeps selected elements and discards the rest. slices.DeleteFunc expresses the inverse operation directly: a predicate marks elements for removal, the retained elements stay in their original order, and the existing backing array is reused. That last property matters. DeleteFunc is not a copying filter. It mutates the supplied slice storage and returns a slice header with the resulting length.

Go 13 Sep 2026 4 min read

Copy Slice Storage with slices.Clone in Go

A slice assignment copies a slice header, not its elements. After b := a, both slice values can still refer to the same backing array, so an element update through one value can appear through the other. slices.Clone provides a compact standard-library operation for the cases that need a copy of the slice elements instead. The function is part of the slices package. Its result has the same length as the input and contains the same elements, but later replacement of an element in one slice does not replace the corresponding element in the other.

Go 13 Sep 2026 4 min read

Compare Slices with Custom Equality in Go

slices.EqualFunc compares two slices position by position while leaving the definition of equality to a supplied function. That makes the operation useful when plain == is unavailable or does not express the relation the program needs. The function also permits the two slices to have different element types: func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any]( s1 S1, s2 S2, eq func(E1, E2) bool, ) bool The result still describes sequence equality. Length, order, and every corresponding pair matter.

Go 13 Sep 2026 4 min read

Compact Adjacent Slice Values with slices.CompactFunc in Go

slices.CompactFunc removes repeated values only when equivalent elements are adjacent. That detail makes it distinct from general deduplication: the function operates on runs, keeps the first element from each run, and leaves separated matches alone. The custom equality function also allows compaction for structs and for equivalence rules that differ from Go’s == operator. Compaction is based on neighboring values The function has this signature: func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S For each run in which neighboring elements satisfy eq, the first element remains in the result. Consider case-insensitive string comparison:

Go 13 Sep 2026 4 min read

Combine Slices with slices.Concat in Go

Concatenating several slices with repeated append calls can make ownership depend on spare capacity in the destination. slices.Concat takes a different contract: it returns a new slice containing all input elements in order. That makes the storage boundary explicit when a combined result must stand apart from its inputs. Added in Go 1.22, slices.Concat also defines the empty case precisely. If the total concatenation has no elements, the result is nil, even when one or more arguments are non-nil empty slices.

Go 12 Sep 2026 4 min read

Traverse Slices in Reverse with slices.Backward in Go

Reverse traversal does not require reversing a slice. Since Go 1.23, slices.Backward exposes the existing elements as an iterator that emits index-value pairs from the last element toward index zero. That distinction matters when element order must stay intact. slices.Reverse changes the slice in place, while a hand-written descending loop couples traversal to index arithmetic. slices.Backward expresses reverse iteration without changing the source. The iterator keeps original indexes The function has this signature:

Go 12 Sep 2026 7 min read

Sort Go Struct Slices with slices.SortFunc

Sorting a slice of structs usually starts with a field: priority, timestamp, name, score, or some combination of them. slices.Sort can’t handle a struct because a struct has no built-in ordering relation. slices.SortFunc fills that gap by taking a comparator that defines the order for the element type. The call is compact, but the comparator is part of the program’s correctness. It has to describe a consistent ordering, and equal comparisons need deliberate handling when records have multiple fields. This article builds that comparator from simple cases to multi-field ordering and covers the mutation and stability details that tend to cause surprises.

Go 12 Sep 2026 6 min read

Sort Go Slices in Place with slices.Sort

A slice arrives out of order, and all you need is ascending numbers or strings. You don’t need a comparator or a wrapper type for that case. slices.Sort handles ordered element types directly and changes the existing slice into ascending order. That directness is useful, but the in-place behavior deserves attention. Sorting a slice can also change what another slice sees when both share the same backing array. This article covers the straightforward call first, then the details that matter once slices move between functions and components.