✖️
puzpuzpuz/xsync パッケージの紹介
こんばんは。ふろーです。
題名通り。
puzpuzpuz/xsync
Go 1.18で導入されたGenericsを使用したgoroutine-safeなMapライブラリです。
従来までは、goroutineによる並列実行に対応したMapを作成する場合は、手動でsync.Mutex
を利用してロックを掛けたり、sync.Map
を使って型変換を実施する必要がありました。
xsyncを使うと、ロックの取得や型の処理をライブラリが管理するため、並列処理に頭を悩ませることが少なくなります。
これまで
sync.Mutex の場合
type SimpleMap struct {
mutex *sync.Mutex
m map[string]any
}
func NewSimpleMap(){
return &SimpleMap{
mutex: &sync.Mutex{},
m: map[string]any{},
}
}
func (sm *SimpleMap) Store(key string, value any) {
// ❌① ロックの取得を管理する必要がある...
sm.mutex.Lock()
defer sm.mutex.Unlock()
sm.m[key] = value
}
// ❌② 戻り値がany型になっている...
func (sm *SimpleMap) Load(key string) any {
sm.mutex.Lock()
defer sm.mutex.Unlock()
return sm.m[key]
}
sync.Map の場合
type SimpleMap struct {
m *sync.Map
}
func NewSimpleMap(){
return &SimpleMap{
m: &sync.Map{},
}
}
func (sm *SimpleMap) Store(key string, value any) {
// ✅① ロックの取得管理をする必要がない!
m.Store(key, value)
}
// ❌② 戻り値はany型のまま...
func (sm *SimpleMap) Load(key string) any {
value := sm.m[key]
// ❓② 型アサーションをすれば型は一応付けれる
// v := sm.m.Load().(any)
return value
}
puzpuzpuz/xsync の場合
xsync.MapOf[K,V] の場合を使うと...
type SimpleMap struct {
// ✅① ロックの取得管理はもちろんやってくれる!
m *xsync.MapOf[string, string] // ✅② Genericsを使うことによってKey,Valueの両方に型を付けれる
}
func NewSimpleMap(){
return &SimpleMap{
m: xsync.NewMapOf[string, string](), // NewMapOf() 関数で初期化が可能
}
}
func (sm *SimpleMap) Store(key string, value string) {
m.Store(key, value)
}
// ✅② 戻り値に型がついている!
func (sm *SimpleMap) Load(key string) string {
return sm.m.Load()
}
短いですが紹介としては以上です。
個人的には便利なので頻繁に使っていますが、他にもxsync.Counter
など、atomicなカウンターなどが用意されているようです。
Discussion