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")
    }
}

如果 mapaLoadOrStore 返回值相同时存储值,我可以立即使用它,但如果不是我必须在前面的代码之后添加类型断言:

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" 

type Map

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 (*Map) LoadOrStore

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)