Метод sync.Map.Swap
Метод sync.Map.Swap атомарно заменяет значение,
связанное с указанным ключом, на новое значение и возвращает
предыдущее значение (если оно было) и булев флаг,
указывающий на наличие ключа в мапе.
Этот метод особенно полезен в конкурентной среде,
где несколько горутин могут одновременно изменять данные.
Первый параметр — ключ для замены, второй — новое значение.
Синтаксис
m.Swap(key, value)
Метод возвращает два значения: предыдущее значение
(тип any) и булев флаг (тип bool).
Флаг равен true, если ключ существовал в мапе,
и false в противном случае.
Пример
Давайте заменим значение по ключу "a" в мапе и проверим результат:
package main
import (
"fmt"
"sync"
)
func main() {
var m sync.Map
// Добавляем начальные значения
m.Store("a", 1)
m.Store("b", 2)
// Заменяем значение по ключу "a" с 1 на 10
old, loaded := m.Swap("a", 10)
fmt.Printf("old=%v, loaded=%v\n", old, loaded)
// Проверяем новое значение
val, _ := m.Load("a")
fmt.Println(val)
}
Результат выполнения кода:
"old=1, loaded=true"
"10"
Пример
Рассмотрим случай, когда ключа нет в мапе:
package main
import (
"fmt"
"sync"
)
func main() {
var m sync.Map
// Пытаемся заменить значение по ключу "x", которого нет
old, loaded := m.Swap("x", 100)
fmt.Printf("old=%v, loaded=%v\n", old, loaded)
// Проверяем, что значение добавилось
val, ok := m.Load("x")
fmt.Printf("val=%v, ok=%v\n", val, ok)
}
Результат выполнения кода:
"old=<nil>, loaded=false"
"val=100, ok=true"
Пример
Использование метода Swap в конкурентной среде
с несколькими горутинами:
package main
import (
"fmt"
"sync"
)
func main() {
var m sync.Map
var wg sync.WaitGroup
// Инициализация мапы
m.Store("counter", 0)
// Запускаем 10 горутин, которые атомарно заменяют значение
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
old, _ := m.Swap("counter", id)
fmt.Printf("goroutine %d: old=%v\n", id, old)
}(i)
}
wg.Wait()
val, _ := m.Load("counter")
fmt.Printf("final value: %v\n", val)
}
Результат выполнения кода (порядок может отличаться):
"goroutine 3: old=0"
"goroutine 2: old=3"
"goroutine 1: old=2"
"goroutine 0: old=1"
"goroutine 5: old=0"
"goroutine 4: old=5"
"goroutine 7: old=4"
"goroutine 6: old=7"
"goroutine 8: old=6"
"goroutine 9: old=8"
"final value: 9"
Смотрите также
-
метод
sync.Map.Store,
который сохраняет значение по ключу в мапе -
метод
sync.Map.Load,
который загружает значение по ключу из мапы -
метод
sync.Map.LoadOrStore,
который загружает или сохраняет значение -
метод
sync.Map.Delete,
который удаляет значение по ключу из мапы