Go 1.28 Introduces Generic Collections: Standardized Set, Tree Map, and Heap
The Go Collections working group’s umbrella proposal for Go 1.28 adds seven generic collection components—including hash‑based Set, ordered tree Map, and a revamped generic heap—addressing long‑standing gaps in the language’s standard library and outlining design trade‑offs and future extensions.
Go’s standard library historically lacked native collection types such as Set, ordered Map, and a convenient heap. To address this, the Go Collections working group submitted an umbrella proposal (Issue #80590) that adds a full suite of generic collections to the Go 1.28 standard library.
New components
container/hash: a generic hash‑based Map. container/set: a generic hash‑based Set. container/tree: a balanced‑tree ordered Map. container/heap/v2: a generic binary heap that replaces the legacy container/heap. container/mapset: a compatibility package that provides Set‑style operations for existing map[T]bool patterns. hash/maphash.Hasher: a standard interface for custom hash functions and equality semantics.
Additional abstract interfaces ( _AbstractCollection, _AbstractSet, _AbstractMap) that model collection behavior using F‑bounded polymorphism.
Custom hash interface
The hash/maphash.Hasher interface forms the foundation of the collection suite. It lets developers supply their own hash function and equality relation, which is useful for structures such as Bloom filters or caches where the default map[K]V hashing is insufficient (e.g., when keys are non‑comparable types or when a different equivalence definition is required). The official documentation includes a Bloom‑filter example.
Abstract collection interfaces
To solve the binary‑method problem, the proposal introduces three non‑exported constraint interfaces:
type _AbstractCollection[E any, C _AbstractCollection[E, C]] interface {
Clear()
Clone() C
Contains(E) bool
ContainsAll(iter.Seq[E]) bool
Len() int
String() string
}Specializations _AbstractSet and _AbstractMap extend this core with methods such as Get, Set, Union, Intersection, etc. The interfaces are deliberately unexported; they serve as documentation for a unified API while allowing the community to observe real‑world usage before any public release.
Minimal‑interface example
The proposal demonstrates how to define a minimal abstraction for a generic operation that removes an arbitrary element from any set:
type _TakeSet[E any, S _TakeSet[E, S]] interface {
All() iter.Seq[E]
Delete(E) bool
}
func Take[S _TakeSet[E, S], E any](set S) (e E, found bool) {
for e = range set.All() {
found = true
set.Delete(e)
break
}
return
}This pattern shows how developers can postpone decisions about which operations belong in the standard interfaces until concrete usage patterns emerge.
Design trade‑offs
Methods return additional information (e.g., whether a Set insertion actually changed the size) to avoid redundant lookups.
The Subset operation is omitted from the core Set interface because its typical O(n) cost offers no asymptotic benefit; users can compose it from existing primitives. DeleteFunc is retained for ordered maps to preserve the expected O(log n) complexity for conditional deletions. Map lacks an Equal method because map values may be incomparable, a limitation that Set does not share.
Functional vs. in‑place APIs
Pure‑functional collection operations (e.g., Union, Intersection) return new collections, while their in‑place variants (e.g., UnionWith) modify the left operand and return no value. This mirrors the approach taken in math/big.Int to prevent accidental misuse.
Impact for Go developers
Hand‑rolled map[T]struct{} patterns for sets can be replaced by set.Set[T], providing clear semantics and built‑in set operations.
Ordered traversal and range queries become native via tree.Map, eliminating the “build a map then sort” workaround.
Custom hash logic gains a standard interface, simplifying the implementation of Bloom filters, caches, and other hash‑sensitive structures.
Existing code that relies on map[T]bool can migrate smoothly using the container/mapset helpers, which expose functions such as Union and Intersection without changing the underlying data structure.
Status and future work
All proposals are currently in draft form; the final API may evolve based on community feedback. The working group also hints at future extensions such as an insertion‑ordered hash map and a Stack type.
Original proposal repository: https://github.com/golang/go/issues/80590
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
TonyBai
Tony Bai's tech world (tonybai.com). Not satisfied with just "knowing how", we strive for mastery. Focused on Go language internals, high-quality engineering practices, and cloud‑native architecture, exploring cutting‑edge intersections of Go and AI. Gophers who pursue technology are welcome—follow me and evolve with Go.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
