container

package
v0.35.2 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: MIT Imports: 1 Imported by: 0

Documentation

Overview

Package container 提供泛型容器微件:并发安全 Map(sync.Map 背书)、 SafeMap(RWMutex)、并发安全 Slice、Set、环形缓冲 Ring、阻塞队列 Queue。 全部零依赖(仅标准库)。

设计参考 go-kratos/kit container(maps/sets/slices)与 go-zero collection 的容器件,全面泛型化并按 Go 习惯收敛语义;v0.8.0 起收编原 collectionx 全部 API(Set/Ring/Queue/SafeMap 类型名与签名不变,仅换 import 路径):

  • Set / Ring 为非并发安全(单 goroutine 或外部加锁使用);
  • Queue / SafeMap / Map / Slice 内建并发安全;
  • Ring 溢出覆盖最旧值(有界有损),Queue 无界无损;
  • Map(sync.Map 背书)适合 key 集合稳定、读多写少的场景; 写冲突频繁或需要 GetOrSet 时用 SafeMap(RWMutex 背书)。

用法:

s := container.NewSet(1, 2, 3)
s.Add(4)

q := container.NewQueue[int]()
q.Put(1)
v, ok := q.Take() // 阻塞直至有元素或关闭

m := container.NewMap[string, *User]()
m.Store("u1", u)

sl := container.NewSlice[int]()
sl.Append(1, 2, 3)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Map

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

Map 并发安全的泛型映射(sync.Map 背书,对标 go-kratos/kit container/maps)。 读多写少、key 集合趋于稳定时性能优于 SafeMap;写冲突频繁或需要 GetOrSet 语义时用 SafeMap。零值不可直接使用,须经 NewMap 创建。

func NewMap

func NewMap[K comparable, V any]() *Map[K, V]

NewMap 创建空映射。

func (*Map[K, V]) Clear

func (m *Map[K, V]) Clear()

Clear 清空全部键值。

func (*Map[K, V]) Delete

func (m *Map[K, V]) Delete(k K)

Delete 删除键(不存在为 no-op)。

func (*Map[K, V]) Len

func (m *Map[K, V]) Len() int

Len 返回键值对数量(通过一次全量 Range 统计,O(n);高频调用请自行缓存)。

func (*Map[K, V]) Load

func (m *Map[K, V]) Load(k K) (V, bool)

Load 读取键值;不存在返回零值与 false。

func (*Map[K, V]) LoadOrStore

func (m *Map[K, V]) LoadOrStore(k K, v V) (V, bool)

LoadOrStore 原子地"不存在则写入":返回当前值与是否本已存在。

func (*Map[K, V]) Range

func (m *Map[K, V]) Range(fn func(k K, v V) bool)

Range 遍历快照;fn 返回 false 提前终止。遍历期间其他 goroutine 的写入 不阻塞,但可见性不保证(标准 sync.Map Range 语义)。

func (*Map[K, V]) Store

func (m *Map[K, V]) Store(k K, v V)

Store 写入键值。

type Queue

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

Queue 无界阻塞 FIFO 队列(并发安全):多生产者/多消费者, Take 阻塞直至有元素或队列关闭。Close 后 Put 直接 panic(与 向已关闭 channel 发送的语义一致)。

func NewQueue

func NewQueue[T any]() *Queue[T]

NewQueue 创建空队列。

func (*Queue[T]) Close

func (q *Queue[T]) Close()

Close 关闭队列:唤醒全部阻塞的 Take(取完余量后返回 false); 幂等。关闭后 Put 会 panic。

func (*Queue[T]) Len

func (q *Queue[T]) Len() int

Len 返回当前积压元素数。

func (*Queue[T]) Put

func (q *Queue[T]) Put(v T)

Put 入队;队列已关闭时 panic(编程错误,与 channel 语义一致)。

func (*Queue[T]) Take

func (q *Queue[T]) Take() (T, bool)

Take 出队一个元素,阻塞直至有元素或队列关闭; 队列关闭且已取空返回零值与 false。

func (*Queue[T]) TryTake

func (q *Queue[T]) TryTake() (T, bool)

TryTake 尝试出队,不阻塞;无元素或已关闭返回零值与 false。

type Ring

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

Ring 定长环形缓冲(非并发安全):生产快于消费最多保留最新 n 个元素, 超出后 Add 覆盖最旧值且保序 FIFO(有界有损,适合"只要最新 n 条"的场景, 如最近请求采样、滑动日志)。

func NewRing

func NewRing[T any](n int) *Ring[T]

NewRing 创建容量为 n 的环形缓冲。n <= 0 属于编程错误,直接 panic。

func (*Ring[T]) Add

func (r *Ring[T]) Add(v T)

Add 写入元素;缓冲已满时覆盖最旧值并前移读指针——保序 FIFO, 任何时刻 Take 得到的都是最新的至多 n 条(最旧值静默丢失)。

func (*Ring[T]) Len

func (r *Ring[T]) Len() int

Len 返回当前积压未取的元素数(不会超过容量 n)。

func (*Ring[T]) Take

func (r *Ring[T]) Take() (T, bool)

Take 按 FIFO 取出元素;已取空返回零值与 false。

type SafeMap

type SafeMap[K comparable, V any] struct {
	// contains filtered or unexported fields
}

SafeMap 并发安全的泛型映射(RWMutex 保护),对标 go-zero collection/SafeMap 的泛型化替代。零值不可直接使用,须经 NewSafeMap 创建。

func NewSafeMap

func NewSafeMap[K comparable, V any]() *SafeMap[K, V]

NewSafeMap 创建空映射。

func (*SafeMap[K, V]) Clear

func (sm *SafeMap[K, V]) Clear()

Clear 清空全部键值。

func (*SafeMap[K, V]) Delete

func (sm *SafeMap[K, V]) Delete(k K)

Delete 删除键(不存在为 no-op)。

func (*SafeMap[K, V]) Get

func (sm *SafeMap[K, V]) Get(k K) (V, bool)

Get 读取键值;不存在返回零值与 false。

func (*SafeMap[K, V]) GetOrSet

func (sm *SafeMap[K, V]) GetOrSet(k K, v V) (V, bool)

GetOrSet 原子地"不存在则写入":返回当前值与是否本已存在。

func (*SafeMap[K, V]) Len

func (sm *SafeMap[K, V]) Len() int

Len 返回键值对数量。

func (*SafeMap[K, V]) Range

func (sm *SafeMap[K, V]) Range(fn func(k K, v V) bool)

Range 遍历快照;fn 返回 false 提前终止。

**先在读锁内取快照,再在锁外遍历**(同 Slice.Range 的做法):

  • 此前遍历期间**一直持着读锁** ⇒ 文档声称的「遍历期间其他 goroutine 的 写入不阻塞」并不成立(Set 要写锁,会被读锁挡住直到遍历结束);
  • 更糟的是回调里写同一个 map 会**死锁**:RWMutex 不可重入,回调的 Set 要写锁、写锁要等读锁释放、读锁要等回调返回——互等。 (实测:回调里 sm.Set 同��个 map ⇒ 永久挂起。)

快照语义:遍历期间的并发写入不影响本次遍历(同 Slice.Range)。

func (*SafeMap[K, V]) Set

func (sm *SafeMap[K, V]) Set(k K, v V)

Set 写入键值。

type Set

type Set[T comparable] map[T]struct{}

Set 泛型集合(非并发安全:单 goroutine 使用,或由调用方加锁保护)。

**零值不可直接使用**(与同包其它容器口径一致):Set 是 map 类型,零值是 nil map,`Add` 会 panic("assignment to entry in nil map")。须经 NewSet 创建。

func NewSet

func NewSet[T comparable](items ...T) Set[T]

NewSet 以给定元素创建集合并去重。

func (Set[T]) Add

func (s Set[T]) Add(v T)

Add 加入元素。

func (Set[T]) AddAll

func (s Set[T]) AddAll(items ...T)

AddAll 批量加入元素。

func (Set[T]) Clone

func (s Set[T]) Clone() Set[T]

Clone 深拷贝出一个新集合。

func (Set[T]) Contains

func (s Set[T]) Contains(v T) bool

Contains 判断元素是否在集合中。

func (Set[T]) Difference

func (s Set[T]) Difference(other Set[T]) Set[T]

Difference 差集:返回存在于 s 但不存在于 other 的新集合。

func (Set[T]) Intersect

func (s Set[T]) Intersect(other Set[T]) Set[T]

Intersect 交集:返回同时存在于两者的新集合。

func (Set[T]) Items

func (s Set[T]) Items() []T

Items 返回全部元素(顺序不保证)。

func (Set[T]) Len

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

Len 返回元素个数。

func (Set[T]) Range

func (s Set[T]) Range(fn func(v T) bool)

Range 遍历全部元素;fn 返回 false 提前终止。

func (Set[T]) Remove

func (s Set[T]) Remove(v T)

Remove 移除元素(不存在为 no-op)。

func (Set[T]) Union

func (s Set[T]) Union(other Set[T]) Set[T]

Union 并集:返回包含两者全部元素的新集合。

type Slice

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

Slice 并发安全的泛型切片(RWMutex 保护,对标 go-kratos/kit container/slices)。 零值不可直接使用,须经 NewSlice 创建。

func NewSlice

func NewSlice[T any](items ...T) *Slice[T]

NewSlice 以给定元素创建切片。

func (*Slice[T]) Append

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

Append 追加元素。

func (*Slice[T]) AppendIfAbsent added in v0.34.0

func (s *Slice[T]) AppendIfAbsent(v T, eq func(a, b T) bool) bool

AppendIfAbsent 原子地「查重 + 追加」(#178):已存在等值元素时返回 false 且 不改动切片;不存在时**在同一把写锁内**追加并返回 true。有序注册表场景 (先注册先命中、查重 fail-fast)对应 SafeMap.GetOrSet 的「一次性原子」承诺—— 先 Range/Snapshot 查重再 Append 是两步,重复注册的 fail-fast 窗口里会插进 两个同名条目。

eq 为 nil 时按 == 比较(interface 相等:动态类型与值都相等;元素动态类型 不可比较时 panic,与 map 访问不可比较键同一运行时契约)。需要深比较 (指针指向内容、切片逐元素)或自定义等价关系(host 别名大小写归一等) 时传入 eq。遍历按注册顺序进行,命中第一个等值元素即停。

func (*Slice[T]) Clear

func (s *Slice[T]) Clear()

Clear 清空全部元素(保留底层数组容量)。

func (*Slice[T]) Delete

func (s *Slice[T]) Delete(i int) bool

Delete 删除下标 i 的元素(后续元素前移);越界为 no-op 并返回 false。

func (*Slice[T]) Get

func (s *Slice[T]) Get(i int) (T, bool)

Get 读取下标 i 的元素;越界返回零值与 false。

func (*Slice[T]) Len

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

Len 返回元素个数。

func (*Slice[T]) Range

func (s *Slice[T]) Range(fn func(i int, v T) bool)

Range 遍历快照副本;fn 返回 false 提前终止。遍历期间的并发写入 不影响本次遍历(每次 Range 都在独立快照上进行)。

func (*Slice[T]) Set

func (s *Slice[T]) Set(i int, v T) bool

Set 覆写下标 i 的元素;越界返回 false。

func (*Slice[T]) Snapshot

func (s *Slice[T]) Snapshot() []T

Snapshot 返回全部元素的拷贝(调用方持有独立副本,可安全修改)。

Jump to

Keyboard shortcuts

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