Как я объясню позже, вы должны использовать указатели для типов 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
).
Синхронизация пакета
import "sync"
карта типа
Карта похожа на интерфейс Go map [interface {}] {}, но безопасна для
одновременное использование несколькими программами без дополнительной блокировки или
координация. Загрузка, хранение и удаление выполняется в амортизированной константе
время.
Тип карты является специализированным. Большая часть кода должна использовать простую карту Go
вместо этого, с отдельной блокировкой или координацией, для лучшей безопасности типа
и чтобы было проще поддерживать другие инварианты вместе с картой
содержание.
Тип карты оптимизирован для двух распространенных случаев использования: (1) когда запись
для данного ключа пишется только один раз, но читается много раз, как в
кэши, которые только растут, или (2) когда несколько операций чтения, записи,
и перезаписать записи для непересекающихся наборов ключей. В этих двух случаях
использование карты может значительно уменьшить конфликт блокировок по сравнению с Go
карта в паре с отдельным Mutex или RWMutex.
Нулевая карта пуста и готова к использованию. Карта не должна быть скопирована
после первого использования.
type Map struct {
// contains filtered or unexported fields
}
func (* Карта) LoadOrStore
func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
LoadOrStore возвращает существующее значение для ключа, если оно присутствует.
В противном случае он сохраняет и возвращает заданное значение. Загруженный результат
Значение true, если значение было загружено, значение false, если сохранено.
A sync.Map
нельзя копировать после первого использования.
В 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)