Concurrency
sync.Map: Loadの結果は型アサーションなしに使えない
sync.Mapは値をanyとして返すため、読み出し側で期待する型を確認する必要があります。
Sourcesync_map.go
Go 1.22
package concurrencyexample
import "sync"
func LoadCount(store *sync.Map, key string) (int, bool) {
value, ok := store.Load(key)
if !ok {
return 0, false
}
count, ok := value.(int)
return count, ok
}Testsync_map_test.go
Go 1.22
package concurrencyexample
import (
"sync"
"testing"
)
func TestSyncMapのLoad結果は型アサーションなしに使えない(t *testing.T) {
var store sync.Map
store.Store("count", 3)
count, ok := LoadCount(&store, "count")
if !ok || count != 3 {
t.Fatalf("LoadCount() = %d, %t; want 3, true", count, ok)
}
store.Store("count", "three")
if _, ok := LoadCount(&store, "count"); ok {
t.Fatal("LoadCount() accepted a string value")
}
}01Assertion
このテストで確認できること
- countにintの3を保存してLoadする
- 同じキーへstringを保存するとintとしての読み出しは失敗する
sync.Mapの値はコンパイル時に型付けされません。キー・値の型が固定で、通常のアクセスが中心なら、mapとsync.RWMutexを組み合わせた設計の方が型安全で意図が明確な場合があります。
OBSERVED RESULT
Store("count", 3) → Load as int: 3, true
Store("count", "three") → Load as int: 0, false