map.LoadOrStore 的地址值 return 是否与嵌套地图的输入相同?
is the adress value return by map.LoadOrStore the same as the input in case of nested maps?
我正在做一个嵌套的 sync.Map 但我想知道如果 LoadOrStore
返回的值与地图的输入相同,我是否可以节省几行代码,我的意思是:
var mapa sync.Map
mapaInterFace, ok := sessiones.LoadOrStore(userID,mapa)
if ok {
mapa,ok=mapaInterFace.(sync.Map)
if !ok{
return errors.New("type assertion")
}
}
如果 mapa
与 LoadOrStore
返回值相同时存储值,我可以立即使用它,但如果不是我必须在前面的代码之后添加类型断言:
mapa,ok=mapaInterFace.(sync.Map)
if !ok{
return errors.New("type assertion")
}
经常做一些会产生一些丑陋的代码
更新:sessiones
是类型 sync.Map
正如我稍后解释的那样,您应该为 sync.Map
类型使用指针。因此,我们可以简化为:
var mapa, mapb = new(sync.Map), new(sync.Map)
var key string
if actual, loaded := mapa.LoadOrStore(key, mapb); loaded {
if maps, ok := actual.(*sync.Map); ok {
mapb = maps
} else {
// handle loaded value type assertion error
}
}
现在分配很便宜,因为我们分配的是指针 (*sync.Map
) 而不是结构 (sync.Map
)。
Package sync
import "sync"
Map is like a Go map[interface{}]interface{} but is safe for
concurrent use by multiple goroutines without additional locking or
coordination. Loads, stores, and deletes run in amortized constant
time.
The Map type is specialized. Most code should use a plain Go map
instead, with separate locking or coordination, for better type safety
and to make it easier to maintain other invariants along with the map
content.
The Map type is optimized for two common use cases: (1) when the entry
for a given key is only ever written once but read many times, as in
caches that only grow, or (2) when multiple goroutines read, write,
and overwrite entries for disjoint sets of keys. In these two cases,
use of a Map may significantly reduce lock contention compared to a Go
map paired with a separate Mutex or RWMutex.
The zero Map is empty and ready for use. A Map must not be copied
after first use.
type Map struct {
// contains filtered or unexported fields
}
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
LoadOrStore returns the existing value for the key if present.
Otherwise, it stores and returns the given value. The loaded result is
true if the value was loaded, false if stored.
A sync.Map
must not be copied after first use.
在 Go 中,所有参数和接收者都是按值传递的,就像通过赋值(副本)一样。例如,go vet
报告 sync.Map
复制错误,
// go vet: variable declaration copies lock value to arg: sync.Map contains sync.Mutex
var m sync.Map
var arg interface{} = m
和
var map1, map2 sync.Map
// go vet: call of map1.LoadOrStore copies lock value: sync.Map contains sync.Mutex
map1.LoadOrStore("key", map2)
使用指针。例如,
var m sync.Map
var arg interface{} = &m
和
var map1, map2 sync.Map
map1.LoadOrStore("key", &map2)
我正在做一个嵌套的 sync.Map 但我想知道如果 LoadOrStore
返回的值与地图的输入相同,我是否可以节省几行代码,我的意思是:
var mapa sync.Map
mapaInterFace, ok := sessiones.LoadOrStore(userID,mapa)
if ok {
mapa,ok=mapaInterFace.(sync.Map)
if !ok{
return errors.New("type assertion")
}
}
如果 mapa
与 LoadOrStore
返回值相同时存储值,我可以立即使用它,但如果不是我必须在前面的代码之后添加类型断言:
mapa,ok=mapaInterFace.(sync.Map)
if !ok{
return errors.New("type assertion")
}
经常做一些会产生一些丑陋的代码
更新:sessiones
是类型 sync.Map
正如我稍后解释的那样,您应该为 sync.Map
类型使用指针。因此,我们可以简化为:
var mapa, mapb = new(sync.Map), new(sync.Map)
var key string
if actual, loaded := mapa.LoadOrStore(key, mapb); loaded {
if maps, ok := actual.(*sync.Map); ok {
mapb = maps
} else {
// handle loaded value type assertion error
}
}
现在分配很便宜,因为我们分配的是指针 (*sync.Map
) 而不是结构 (sync.Map
)。
Package sync
import "sync"
Map is like a Go map[interface{}]interface{} but is safe for concurrent use by multiple goroutines without additional locking or coordination. Loads, stores, and deletes run in amortized constant time.
The Map type is specialized. Most code should use a plain Go map instead, with separate locking or coordination, for better type safety and to make it easier to maintain other invariants along with the map content.
The Map type is optimized for two common use cases: (1) when the entry for a given key is only ever written once but read many times, as in caches that only grow, or (2) when multiple goroutines read, write, and overwrite entries for disjoint sets of keys. In these two cases, use of a Map may significantly reduce lock contention compared to a Go map paired with a separate Mutex or RWMutex.
The zero Map is empty and ready for use. A Map must not be copied after first use.
type Map struct { // contains filtered or unexported fields }
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
LoadOrStore returns the existing value for the key if present. Otherwise, it stores and returns the given value. The loaded result is true if the value was loaded, false if stored.
A
sync.Map
must not be copied after first use.
在 Go 中,所有参数和接收者都是按值传递的,就像通过赋值(副本)一样。例如,go vet
报告 sync.Map
复制错误,
// go vet: variable declaration copies lock value to arg: sync.Map contains sync.Mutex
var m sync.Map
var arg interface{} = m
和
var map1, map2 sync.Map
// go vet: call of map1.LoadOrStore copies lock value: sync.Map contains sync.Mutex
map1.LoadOrStore("key", map2)
使用指针。例如,
var m sync.Map
var arg interface{} = &m
和
var map1, map2 sync.Map
map1.LoadOrStore("key", &map2)