Documentation
¶
Overview ¶
Package syncx 提供泛型并发数据结构,是标准库 sync 包的类型安全扩展。
目前提供:
Index ¶
- type GroupStateStore
- type Lazy
- type Map
- func (m *Map[K, V]) Clear()
- func (m *Map[K, V]) Compute(key K, fn func(old V, exists bool) (newVal V, store bool)) (V, bool)
- func (m *Map[K, V]) Delete(key K)
- func (m *Map[K, V]) DeleteIf(fn func(key K, val V) bool)
- func (m *Map[K, V]) GetOrCreate(key K, newFn func() V) V
- func (m *Map[K, V]) Has(key K) bool
- func (m *Map[K, V]) Len() int
- func (m *Map[K, V]) Load(key K) (V, bool)
- func (m *Map[K, V]) LoadAndDelete(key K) (V, bool)
- func (m *Map[K, V]) LoadOrStore(key K, val V) (actual V, loaded bool)
- func (m *Map[K, V]) Range(fn func(key K, val V) bool)
- func (m *Map[K, V]) Store(key K, val V)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type GroupStateStore ¶
GroupStateStore 是泛型的 per-group 状态管理器,基于 Map[string, *T] 构建。
相比直接使用 Map[string, *T],额外提供无参的 GroupStateStore.GetOrCreate 便捷方法 (自动以 new(T) 作为缺失 key 的构造函数,无需调用方传入工厂函数)。
其余方法(Load / Delete / DeleteIf / Range / Len 等)由嵌入的 Map 直接提供, 不再重复实现。
典型用法(词语接龙/钓鱼/游戏等 per-group 状态):
type gameState struct {
mu sync.Mutex
active bool
round int
}
var store syncx.GroupStateStore[gameState]
state := store.GetOrCreate(groupID)
state.mu.Lock()
defer state.mu.Unlock()
state.active = true
注意:T 本身的并发保护由调用方负责(通常在 T 内内嵌 sync.Mutex)。 零值直接可用,使用后不得复制。
func (*GroupStateStore[T]) Get ¶
func (s *GroupStateStore[T]) Get(groupID string) (*T, bool)
Get 是 Map.Load 的别名
func (*GroupStateStore[T]) GetOrCreate ¶
func (s *GroupStateStore[T]) GetOrCreate(groupID string) *T
GetOrCreate 返回 groupID 对应的状态指针。
若该 groupID 不存在,自动创建零值 *T 并存储后返回。 多个 goroutine 并发调用是安全的;同一 key 只会创建一次。
type Lazy ¶
type Lazy[T any] struct { // contains filtered or unexported fields }
Lazy 提供泛型懒初始化:首次调用 Lazy.Get 时执行 init 函数, 结果被缓存,后续调用直接返回缓存值,无额外锁开销。
使用 NewLazy 构造;零值不可用(init 为 nil 会 panic)。
示例:
loader := syncx.NewLazy(func() *Config {
cfg, _ := loadConfigFromDisk()
return cfg
})
// 首次调用触发加载,后续调用直接返回缓存:
cfg := loader.Get()
type Map ¶
type Map[K comparable, V any] struct { // contains filtered or unexported fields }
Map 是基于 sync.RWMutex 的泛型并发映射。
相比 sync.Map,提供编译期类型安全(无需运行时类型断言), 并附加 Map.Compute、Map.Len、Map.Has、Map.Clear 等实用方法。
零值直接可用,无需显式初始化。Map 在首次使用后不得复制。
适用场景:
- 混合读写负载,通过 RWMutex 实现并发安全。
- 需要原子读-改-写操作(Map.Compute)。
- 消除 mu sync.RWMutex + map[K]V 模板样板代码。
示例:
var m syncx.Map[string, int]
m.Store("a", 1)
v, ok := m.Load("a") // v=1, ok=true
m.Compute("a", func(old int, exists bool) (int, bool) {
return old + 1, true // 原子自增
})
func (*Map[K, V]) Compute ¶
Compute 在持有写锁的情况下对 key 执行原子读-改-写操作。
fn 接收当前值 old 及是否存在 exists,返回:
- (newVal, true) → 将 newVal 写入 map
- (_, false) → 从 map 删除 key(key 不存在时为空操作)
返回 fn 的返回值 (newVal, store),供调用方检查最终状态。 若需在调用方获取额外结果,可在 fn 内通过闭包捕获变量。
func (*Map[K, V]) DeleteIf ¶
DeleteIf 按条件批量删除条目。
遍历所有条目,当 fn 返回 true 时删除该条目。 fn 在持有写锁期间调用,因此 fn 内部不应再操作同一 Map(会死锁)。
典型用途:定期 GC 超时的游戏会话。
store.DeleteIf(func(_ string, s *gameState) bool {
s.mu.Lock()
defer s.mu.Unlock()
return time.Since(s.StartTime) > 5*time.Minute
})
func (*Map[K, V]) GetOrCreate ¶
func (m *Map[K, V]) GetOrCreate(key K, newFn func() V) V
GetOrCreate 返回 key 对应的值;若 key 不存在,则调用 newFn 创建、存储并返回新值。
使用读写双检锁(read→write double-check)保证并发安全: 快路径仅需读锁,只有真正缺失时才升级写锁,并发创建只发生一次。
newFn 在持有写锁时调用,不应在 newFn 内再操作同一 Map(会死锁)。
func (*Map[K, V]) LoadAndDelete ¶
LoadAndDelete 删除 key 并返回删除前的值及是否存在。
func (*Map[K, V]) LoadOrStore ¶
LoadOrStore 若 key 已存在则返回现有值(loaded=true), 否则存入 val 并返回 val(loaded=false)。