== Go does not have atomic variables, only atomic access to variables Suppose, hypothetically, that you have a structure full of [[expvar variables https://golang.org/pkg/expvar/]]. You would like to expose all of them in one operation with _expvar.Func_, using some code that goes roughly like this: > var events struct { > Var1, Var2, Var3 expvar.Int > } > > func ReportStats() interface{} { > return events > } Ignoring for the moment [[how this won't work GoExpvarFuncLimit]], let's ask a more fundamental question: *is this a safe, race-free operation*? On first blush it looks like it should be, since the expvar types are all safe for concurrent access through their methods. However, this is actually not the case, due to an important thing about Go: > ~~Go does not have atomic variables, only atomic access to > variables~~. Some languages support special atomic variable types. These variable types are defined so that absolutely all (safe) language access to the variables that you can perform is atomic, even mundane accesses like '_acopy = avar_' or '_return avar_'. In such a language, _ReportStats()_ would be safe. Go is not such a language. Go has no atomic variable types; instead, all it has is atomic access to ordinary non-atomic variables (through [[the _sync/atomic_ package https://golang.org/pkg/sync/atomic/]]). This means that language level operations like '_acopy = avar_' or '_return avar_' are not atomic and are not protected against various sorts of data races that create inconsistencies or other dangers. The expvar types are no exception to this; their public methods are concurrency safe (which is achieved in various ways), but the actual underlying unexported fields inside them are not safe if you do things like make copies of them, as _ReportStats()_ does when it says '_return events_'. In some cases you can get a warning about this, as _go vet_ will complain about the related issue of making a copy of a [[_sync_ https://golang.org/pkg/sync/]] lock (or anything containing one, such as a _sync.RWMutex_). Some types that are intended to be accessed only atomically will have an embedded lock, and so making a copy of them will cause _go vet_ to complain about copying their embedded lock. However, not all 'intended to be atomic' types use embedded locks, so not all will be caught by this check; for example, _expvar.String_ has an embedded lock (in a _sync.RWMutex_) and so will provoke _go vet_ complaints when copied, but _expvar.Int_ currently doesn't have an embedded lock and _go vet_ will not warn you if you copy one and give yourself a potential data race. (There may someday be a way to annotate types so that _go vet_ knows to complain about making copies of them, but as far as I know there's no way to do that today. If such a way is added, presumably all _expvar_ variable types would get that annotation.)