I want to write some code like this:
var myValue interface{}
func GetMyValue() interface{} {
return atomic.Load(myValue)
}
func StoreMyValue(newValue interface{}) {
atomic.Store(myValue, newValue)
}
It seems like that i can use LoadUintptr(addr *uintptr) (val uintptr) and StoreUintptr(addr *uintptr, val uintptr) in atomic package to achive this,but i do not know how to convert between uintptr,unsafe.Pointer and interface{}.
If i do it like this:
var V interface{}
func F(v interface{}) {
p := unsafe.Pointer(&V)
atomic.StorePointer(&p, unsafe.Pointer(&v))
}
func main() {
V = 1
F(2)
fmt.Println(V)
}
the V will always be 1
If I'm not mistaken you want atomic Value. You can store and fetch values atomically with it (signatures are interface{}
but you should put same type into it). It does some unsafe pointer stuff under the hood like what you wanted to do.
Sample from docs:
var config 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
}
}()
}
Here's a way to use atomic.StorePointer
and atomic.LoadPointer
(based on your example):
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
var addr unsafe.Pointer
func GetMyValue() *interface{} {
return (*interface{})(atomic.LoadPointer(&addr))
}
func StoreMyValue(newValue *interface{}) {
atomic.StorePointer(&addr, unsafe.Pointer(newValue))
}
func main() {
var i interface{}
i = 1
StoreMyValue(&i)
fmt.Println("before:", *GetMyValue())
i = 2
StoreMyValue(&i)
fmt.Println("after", *GetMyValue())
}
Playground link
Note that this will not make your object thread-safe. Only the pointer is stored/loaded atomically. Also, I would avoid using interface{}
and prefer concrete types whenever possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With