Пакет atomic
Обзор
Пакет atomic предоставляет низкоуровневые атомарные примитивы работы с памятью, полезные для реализации алгоритмов синхронизации.
Для корректного использования этих функций требуется большая осторожность. За исключением особых низкоуровневых приложений, для синхронизации лучше использовать каналы или средства пакета sync. Делитесь памятью посредством обмена сообщениями; не обменивайтесь сообщениями посредством совместного использования памяти.
Операция обмена, реализованная функциями SwapT, является атомарным эквивалентом:
old = *addr *addr = new return old
Операция сравнения и обмена, реализованная функциями CompareAndSwapT, является атомарным эквивалентом:
if *addr == old {
*addr = new
return true
}
return false
Операция сложения, реализованная функциями AddT, является атомарным эквивалентом:
*addr += delta return *addr
Операции загрузки и сохранения, реализованные функциями LoadT и StoreT, являются атомарными эквивалентами выражений "return *addr" и "*addr = val".
Согласно терминологии модели памяти Go, если эффект атомарной операции A наблюдается атомарной операцией B, то A «синхронизируется перед» B. Кроме того, все атомарные операции, выполняемые в программе, ведут себя так, как если бы они выполнялись в некотором последовательно согласованном порядке. Это определение обеспечивает ту же семантику, что и последовательно согласованные атомарные операции в C++ и volatile-переменные в Java.
Поддерживаются только некоторые размеры целых чисел: на многих архитектурах атомарные операции над целыми числами, размер которых не равен размеру машинного слова, неэффективны или невозможны. Например, Bool может быть больше встроенного типа bool.
Указатель
Примеры
Файлы пакета
doc.go doc_64.go type.go value.go
func AddInt32
func AddInt32(addr *int32, delta int32) (new int32)
AddInt32 атомарно прибавляет delta к *addr и возвращает новое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int32.Add.
func AddInt64
func AddInt64(addr *int64, delta int64) (new int64)
AddInt64 атомарно прибавляет delta к *addr и возвращает новое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int64.Add (особенно если вы ориентируетесь на 32-разрядные платформы; см. раздел об ошибках).
func AddUint32
func AddUint32(addr *uint32, delta uint32) (new uint32)
AddUint32 атомарно прибавляет delta к *addr и возвращает новое значение. Чтобы вычесть из x положительную константу c со знаком, выполните AddUint32(&x, ^uint32(c-1)). В частности, чтобы уменьшить x на единицу, выполните AddUint32(&x, ^uint32(0)). Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint32.Add.
func AddUint64
func AddUint64(addr *uint64, delta uint64) (new uint64)
AddUint64 атомарно прибавляет delta к *addr и возвращает новое значение. Чтобы вычесть из x положительную константу c со знаком, выполните AddUint64(&x, ^uint64(c-1)). В частности, чтобы уменьшить x на единицу, выполните AddUint64(&x, ^uint64(0)). Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint64.Add (особенно если вы ориентируетесь на 32-разрядные платформы; см. раздел об ошибках).
func AddUintptr
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
AddUintptr атомарно прибавляет delta к *addr и возвращает новое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uintptr.Add.
func AndInt32 1.23
func AndInt32(addr *int32, mask int32) (old int32)
AndInt32 атомарно выполняет побитовую операцию AND над *addr с использованием битовой маски mask и возвращает старое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int32.And.
func AndInt64 1.23
func AndInt64(addr *int64, mask int64) (old int64)
AndInt64 атомарно выполняет побитовую операцию AND над *addr с использованием битовой маски mask и возвращает старое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int64.And.
func AndUint32 1.23
func AndUint32(addr *uint32, mask uint32) (old uint32)
AndUint32 атомарно выполняет побитовую операцию AND над *addr с использованием битовой маски mask и возвращает старое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint32.And.
func AndUint64 1.23
func AndUint64(addr *uint64, mask uint64) (old uint64)
AndUint64 атомарно выполняет побитовую операцию AND над *addr с использованием битовой маски mask и возвращает старое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint64.And.
func AndUintptr 1.23
func AndUintptr(addr *uintptr, mask uintptr) (old uintptr)
AndUintptr атомарно выполняет побитовую операцию AND над *addr с использованием битовой маски mask и возвращает старое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uintptr.And.
func CompareAndSwapInt32
func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
CompareAndSwapInt32 выполняет операцию сравнения и замены для значения int32. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int32.CompareAndSwap.
func CompareAndSwapInt64
func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
CompareAndSwapInt64 выполняет операцию сравнения и замены для значения int64. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int64.CompareAndSwap (особенно если вы ориентируетесь на 32-разрядные платформы; см. раздел об ошибках).
func CompareAndSwapPointer
func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
CompareAndSwapPointer выполняет операцию сравнения и замены для значения unsafe.Pointer. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Pointer.CompareAndSwap.
func CompareAndSwapUint32
func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
CompareAndSwapUint32 выполняет операцию сравнения и замены для значения uint32. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint32.CompareAndSwap.
func CompareAndSwapUint64
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
CompareAndSwapUint64 выполняет операцию сравнения и замены для значения uint64. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint64.CompareAndSwap (особенно если вы ориентируетесь на 32-разрядные платформы; см. раздел об ошибках).
func CompareAndSwapUintptr
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
CompareAndSwapUintptr выполняет операцию сравнения и замены для значения uintptr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uintptr.CompareAndSwap.
func LoadInt32
func LoadInt32(addr *int32) (val int32)
LoadInt32 атомарно загружает значение по адресу *addr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int32.Load.
func LoadInt64
func LoadInt64(addr *int64) (val int64)
LoadInt64 атомарно загружает значение по адресу *addr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int64.Load (особенно если вы ориентируетесь на 32-разрядные платформы; см. раздел об ошибках).
func LoadPointer
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
LoadPointer атомарно загружает значение по адресу *addr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Pointer.Load.
func LoadUint32
func LoadUint32(addr *uint32) (val uint32)
LoadUint32 атомарно загружает значение по адресу *addr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint32.Load.
func LoadUint64
func LoadUint64(addr *uint64) (val uint64)
LoadUint64 атомарно загружает значение по адресу *addr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uint64.Load (особенно если вы ориентируетесь на 32-разрядные платформы; см. раздел об ошибках).
func LoadUintptr
func LoadUintptr(addr *uintptr) (val uintptr)
LoadUintptr атомарно загружает значение по адресу *addr. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Uintptr.Load.
func OrInt32 1.23
func OrInt32(addr *int32, mask int32) (old int32)
OrInt32 атомарно выполняет побитовую операцию OR над *addr с использованием битовой маски mask и возвращает старое значение. Вместо неё рассмотрите более удобный и менее подверженный ошибкам вариант — Int32.Or.
func OrInt64 1.23
func OrInt64(addr *int64, mask int64) (old int64)
OrInt64 атомарно выполняет побитовую операцию ИЛИ над *addr, используя битовую маску, заданную как mask, и возвращает старое значение. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Int64.Or.
func OrUint32 1.23
func OrUint32(addr *uint32, mask uint32) (old uint32)
OrUint32 атомарно выполняет побитовую операцию ИЛИ над *addr, используя битовую маску, заданную как mask, и возвращает старое значение. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uint32.Or.
func OrUint64 1.23
func OrUint64(addr *uint64, mask uint64) (old uint64)
OrUint64 атомарно выполняет побитовую операцию ИЛИ над *addr, используя битовую маску, заданную как mask, и возвращает старое значение. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uint64.Or.
func OrUintptr 1.23
func OrUintptr(addr *uintptr, mask uintptr) (old uintptr)
OrUintptr атомарно выполняет побитовую операцию ИЛИ над *addr, используя битовую маску, заданную как mask, и возвращает старое значение. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uintptr.Or.
func StoreInt32
func StoreInt32(addr *int32, val int32)
StoreInt32 атомарно сохраняет val в *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Int32.Store.
func StoreInt64
func StoreInt64(addr *int64, val int64)
StoreInt64 атомарно сохраняет val в *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Int64.Store (особенно если вы разрабатываете для 32-разрядных платформ; см. раздел об ошибках).
func StorePointer
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
StorePointer атомарно сохраняет val в *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Pointer.Store.
func StoreUint32
func StoreUint32(addr *uint32, val uint32)
StoreUint32 атомарно сохраняет val в *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uint32.Store.
func StoreUint64
func StoreUint64(addr *uint64, val uint64)
StoreUint64 атомарно сохраняет val в *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uint64.Store (особенно если вы разрабатываете для 32-разрядных платформ; см. раздел об ошибках).
func StoreUintptr
func StoreUintptr(addr *uintptr, val uintptr)
StoreUintptr атомарно сохраняет val в *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uintptr.Store.
func SwapInt32 1.2
func SwapInt32(addr *int32, new int32) (old int32)
SwapInt32 атомарно сохраняет new в *addr и возвращает предыдущее значение *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Int32.Swap.
func SwapInt64 1.2
func SwapInt64(addr *int64, new int64) (old int64)
SwapInt64 атомарно сохраняет new в *addr и возвращает предыдущее значение *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Int64.Swap (особенно если вы разрабатываете для 32-разрядных платформ; см. раздел об ошибках).
func SwapPointer 1.2
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
SwapPointer атомарно сохраняет new в *addr и возвращает предыдущее значение *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Pointer.Swap.
func SwapUint32 1.2
func SwapUint32(addr *uint32, new uint32) (old uint32)
SwapUint32 атомарно сохраняет new в *addr и возвращает предыдущее значение *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uint32.Swap.
func SwapUint64 1.2
func SwapUint64(addr *uint64, new uint64) (old uint64)
SwapUint64 атомарно сохраняет new в *addr и возвращает предыдущее значение *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uint64.Swap (особенно если вы разрабатываете для 32-разрядных платформ; см. раздел об ошибках).
func SwapUintptr 1.2
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
SwapUintptr атомарно сохраняет new в *addr и возвращает предыдущее значение *addr. Вместо этого рекомендуется использовать более удобный и менее подверженный ошибкам метод Uintptr.Swap.
type Bool 1.19
Bool — это атомарное логическое значение. Нулевое значение — false.
После первого использования Bool нельзя копировать.
type Bool struct {
// contains filtered or unexported fields
}
func (*Bool) CompareAndSwap 1.19
func (x *Bool) CompareAndSwap(old, new bool) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для логического значения x.
func (*Bool) Load 1.19
func (x *Bool) Load() bool
Load атомарно загружает и возвращает значение, сохранённое в x.
func (*Bool) Store 1.19
func (x *Bool) Store(val bool)
Store атомарно сохраняет val в x.
func (*Bool) Swap 1.19
func (x *Bool) Swap(new bool) (old bool)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Int32 1.19
Int32 — это атомарное значение int32. Нулевое значение — ноль.
После первого использования Int32 нельзя копировать.
type Int32 struct {
// contains filtered or unexported fields
}
func (*Int32) Add 1.19
func (x *Int32) Add(delta int32) (new int32)
Add атомарно прибавляет delta к x и возвращает новое значение.
func (*Int32) And 1.23
func (x *Int32) And(mask int32) (old int32)
And атомарно выполняет побитовую операцию И над x, используя битовую маску, заданную как mask, и возвращает старое значение.
func (*Int32) CompareAndSwap 1.19
func (x *Int32) CompareAndSwap(old, new int32) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для x.
func (*Int32) Load 1.19
func (x *Int32) Load() int32
Load атомарно загружает и возвращает значение, сохранённое в x.
func (*Int32) Or 1.23
func (x *Int32) Or(mask int32) (old int32)
Or атомарно выполняет побитовую операцию ИЛИ над x, используя битовую маску, заданную как mask, и возвращает старое значение.
func (*Int32) Store 1.19
func (x *Int32) Store(val int32)
Store атомарно сохраняет val в x.
func (*Int32) Swap 1.19
func (x *Int32) Swap(new int32) (old int32)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Int64 1.19
Int64 — это атомарное значение int64. Нулевое значение — ноль.
После первого использования Int64 нельзя копировать.
type Int64 struct {
// contains filtered or unexported fields
}
func (*Int64) Add 1.19
func (x *Int64) Add(delta int64) (new int64)
Add атомарно прибавляет delta к x и возвращает новое значение.
func (*Int64) And 1.23
func (x *Int64) And(mask int64) (old int64)
And атомарно выполняет побитовую операцию AND над x, используя битовую маску mask, и возвращает старое значение.
func (*Int64) CompareAndSwap 1.19
func (x *Int64) CompareAndSwap(old, new int64) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для x.
func (*Int64) Load 1.19
func (x *Int64) Load() int64
Load атомарно загружает и возвращает значение, хранящееся в x.
func (*Int64) Or 1.23
func (x *Int64) Or(mask int64) (old int64)
Or атомарно выполняет побитовую операцию OR над x, используя битовую маску mask, и возвращает старое значение.
func (*Int64) Store 1.19
func (x *Int64) Store(val int64)
Store атомарно сохраняет val в x.
func (*Int64) Swap 1.19
func (x *Int64) Swap(new int64) (old int64)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Pointer
Pointer — это атомарный указатель типа *T. Нулевое значение — nil *T.
После первого использования Pointer нельзя копировать.
type Pointer[T any] struct {
// contains filtered or unexported fields
}
func (*Pointer[T]) CompareAndSwap
func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для x.
func (*Pointer[T]) Load
func (x *Pointer[T]) Load() *T
Load атомарно загружает и возвращает значение, хранящееся в x.
func (*Pointer[T]) Store
func (x *Pointer[T]) Store(val *T)
Store атомарно сохраняет val в x.
func (*Pointer[T]) Swap
func (x *Pointer[T]) Swap(new *T) (old *T)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Uint32 1.19
Uint32 — это атомарное значение типа uint32. Нулевое значение — ноль.
После первого использования Uint32 нельзя копировать.
type Uint32 struct {
// contains filtered or unexported fields
}
func (*Uint32) Add 1.19
func (x *Uint32) Add(delta uint32) (new uint32)
Add атомарно прибавляет delta к x и возвращает новое значение.
func (*Uint32) And 1.23
func (x *Uint32) And(mask uint32) (old uint32)
And атомарно выполняет побитовую операцию AND над x, используя битовую маску mask, и возвращает старое значение.
func (*Uint32) CompareAndSwap 1.19
func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для x.
func (*Uint32) Load 1.19
func (x *Uint32) Load() uint32
Load атомарно загружает и возвращает значение, хранящееся в x.
func (*Uint32) Or 1.23
func (x *Uint32) Or(mask uint32) (old uint32)
Or атомарно выполняет побитовую операцию OR над x, используя битовую маску mask, и возвращает старое значение.
func (*Uint32) Store 1.19
func (x *Uint32) Store(val uint32)
Store атомарно сохраняет val в x.
func (*Uint32) Swap 1.19
func (x *Uint32) Swap(new uint32) (old uint32)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Uint64 1.19
Uint64 — это атомарное значение типа uint64. Нулевое значение — ноль.
После первого использования Uint64 нельзя копировать.
type Uint64 struct {
// contains filtered or unexported fields
}
func (*Uint64) Add 1.19
func (x *Uint64) Add(delta uint64) (new uint64)
Add атомарно прибавляет delta к x и возвращает новое значение.
func (*Uint64) And 1.23
func (x *Uint64) And(mask uint64) (old uint64)
And атомарно выполняет побитовую операцию AND над x, используя битовую маску mask, и возвращает старое значение.
func (*Uint64) CompareAndSwap 1.19
func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для x.
func (*Uint64) Load 1.19
func (x *Uint64) Load() uint64
Load атомарно загружает и возвращает значение, хранящееся в x.
func (*Uint64) Or 1.23
func (x *Uint64) Or(mask uint64) (old uint64)
Or атомарно выполняет побитовую операцию OR над x, используя битовую маску mask, и возвращает старое значение.
func (*Uint64) Store 1.19
func (x *Uint64) Store(val uint64)
Store атомарно сохраняет val в x.
func (*Uint64) Swap 1.19
func (x *Uint64) Swap(new uint64) (old uint64)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Uintptr 1.19
Uintptr — это атомарное значение типа uintptr. Нулевое значение — ноль.
После первого использования Uintptr нельзя копировать.
type Uintptr struct {
// contains filtered or unexported fields
}
func (*Uintptr) Add 1.19
func (x *Uintptr) Add(delta uintptr) (new uintptr)
Add атомарно прибавляет delta к x и возвращает новое значение.
func (*Uintptr) And 1.23
func (x *Uintptr) And(mask uintptr) (old uintptr)
And атомарно выполняет побитовую операцию AND над x, используя битовую маску mask, и возвращает старое значение.
func (*Uintptr) CompareAndSwap 1.19
func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool)
CompareAndSwap выполняет операцию сравнения и обмена для x.
func (*Uintptr) Load 1.19
func (x *Uintptr) Load() uintptr
Load атомарно загружает и возвращает значение, хранящееся в x.
func (*Uintptr) Or 1.23
func (x *Uintptr) Or(mask uintptr) (old uintptr)
Or атомарно выполняет побитовую операцию OR над x, используя битовую маску mask, и возвращает старое значение.
func (*Uintptr) Store 1.19
func (x *Uintptr) Store(val uintptr)
Store атомарно сохраняет val в x.
func (*Uintptr) Swap 1.19
func (x *Uintptr) Swap(new uintptr) (old uintptr)
Swap атомарно сохраняет new в x и возвращает предыдущее значение.
type Value 1.4
Value обеспечивает атомарную загрузку и сохранение значения с неизменным типом. Нулевое значение Value возвращает nil при вызове Value.Load. После вызова Value.Store копировать Value нельзя.
После первого использования Value нельзя копировать.
type Value struct {
// contains filtered or unexported fields
}
Пример (Config)
В следующем примере показано, как использовать Value для периодического обновления конфигурации программы и передачи изменений рабочим горутинам.
Код:
var config atomic.Value // holds current server configuration
// Create initial config value and store into config.
config.Store(loadConfig())
go func() {
// Reload config every 10 seconds
// and update config value with the new version.
for {
time.Sleep(10 * time.Second)
config.Store(loadConfig())
}
}()
// Create worker goroutines that handle incoming requests
// using the latest config value.
for i := 0; i < 10; i++ {
go func() {
for r := range requests() {
c := config.Load()
// Handle request r using config c.
_, _ = r, c
}
}()
}
Пример (ReadMostly)
В следующем примере показано, как поддерживать масштабируемую структуру данных, которую часто читают, но редко обновляют, используя идиому копирования при записи.
Код:
type Map map[string]string
var m atomic.Value
m.Store(make(Map))
var mu sync.Mutex // used only by writers
// read function can be used to read the data without further synchronization
read := func(key string) (val string) {
m1 := m.Load().(Map)
return m1[key]
}
// insert function can be used to update the data without further synchronization
insert := func(key, val string) {
mu.Lock() // synchronize with other potential writers
defer mu.Unlock()
m1 := m.Load().(Map) // load current value of the data structure
m2 := make(Map) // create a new value
for k, v := range m1 {
m2[k] = v // copy all data from the current object to the new one
}
m2[key] = val // do the update that we need
m.Store(m2) // atomically replace the current object with the new one
// At this point all new readers start working with the new version.
// The old version will be garbage collected once the existing readers
// (if any) are done with it.
}
_, _ = read, insert
func (*Value) CompareAndSwap 1.17
func (v *Value) CompareAndSwap(old, new any) (swapped bool)
CompareAndSwap выполняет операцию сравнения и замены для Value.
Все вызовы CompareAndSwap для одного и того же Value должны использовать значения одного и того же конкретного типа. CompareAndSwap с несовместимым типом вызывает панику, как и CompareAndSwap(old, nil).
func (*Value) Load 1.4
func (v *Value) Load() (val any)
Load возвращает значение, установленное последним вызовом Store. Возвращает nil, если для этого Value не было вызовов Store.
func (*Value) Store 1.4
func (v *Value) Store(val any)
Store устанавливает значение Value v равным val. Все вызовы Store для одного и того же Value должны использовать значения одного и того же конкретного типа. Store с несовместимым типом вызывает панику, как и Store(nil).
func (*Value) Swap 1.17
func (v *Value) Swap(new any) (old any)
Swap сохраняет new в Value и возвращает предыдущее значение. Возвращает nil, если Value пуст.
Все вызовы Swap для одного и того же Value должны использовать значения одного и того же конкретного типа. Swap с несовместимым типом вызывает панику, как и Swap(nil).
Ошибки
- ☞
На 386 функции для 64-разрядных значений используют инструкции, недоступные до появления Pentium MMX.
На ARM, кроме Linux, функции для 64-разрядных значений используют инструкции, недоступные до ядра ARMv6k.
На ARM, 386 и 32-разрядном MIPS вызывающий код должен обеспечить 64-разрядное выравнивание 64-разрядных слов, к которым выполняется атомарный доступ с помощью примитивных атомарных функций (типы Int64 и Uint64 выравниваются автоматически). Можно рассчитывать, что первое слово в выделенной структуре, массиве или срезе, глобальной переменной или локальной переменной (поскольку в 32-разрядных архитектурах объект 64-разрядных атомарных операций будет перемещён в кучу) выровнено по 64-разрядной границе.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/sync/atomic/