gogenericsinterfaceatomic

Can atomic.Value store a zero interface{}?


package atomicvalue

import "sync/atomic"

type AtomicValue[T any] struct {
    v atomic.Value
}

func (av *AtomicValue[T]) Load() T {
    if v := av.v.Load(); v != nil {
        return v.(T)
    } else {
        var v T
        return v
    }
}

func (av *AtomicValue[T]) Store(value T) {
    av.v.Store(value)
}

func (av *AtomicValue[T]) CompareAndSwap(old, new T) bool {
    return av.v.CompareAndSwap(old, new)
}

func (av *AtomicValue[T]) Swap(new T) (old T) {
    old = av.Load()
    av.Store(new)
    return old
}

I wrap the atomic.Value to a generic type. I handled the zero value in Load() function, but I can't store nil.

type MyInterface interface{
    One()
    Two()
    Three()
}

var value atomicvalue.AtomicValue[MyInterface]
bar:=&MyStruct{} // MyStruct implements MyInterface
value.store(bar) // ok
value.store(nil) // panic there

When I store a nil, there will be a panic:

panic: sync/atomic: store of nil value into Value

Solution

  • According to the docs:

    A Value provides an atomic load and store of a consistently typed value.

    So this works:

        v := atomic.Value{}
        var x *int
        v.Store(x)
    

    But this doesn't, nor would any other nil interface value, because the actual type of the value is not consistent:

        v := atomic.Value{}
        var x any
        v.Store(x)