Fundamentals 15 min read

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.

TonyBai
TonyBai
TonyBai
Go 1.28 Introduces Generic Collections: Standardized Set, Tree Map, and Heap

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

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GoGenericsCollectionsHeapStandard LibrarySetTree Map
TonyBai
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.