go - Go atomic store 后跟 atomic load 在例程中表现异常
问题描述
我正在尝试将地图存储为不安全的。指针并尝试稍后检索它。下面是代码片段:
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
type MapHolder struct {
ptr unsafe.Pointer
}
func (m MapHolder) Set(myMap map[string]int64) {
atomic.StorePointer(&m.ptr, unsafe.Pointer(&myMap))
fmt.Printf("The pointer value is: %v\n", atomic.LoadPointer(&m.ptr))
}
func (m MapHolder) Get() map[string]int64 {
ptr := atomic.LoadPointer(&m.ptr)
if ptr == nil {
fmt.Printf("Why is this pointer value nil?")
return nil
} else {
return *(*map[string]int64)(ptr)
}
}
func main() {
var m MapHolder
test := make(map[string]int64)
test["hello"] = 1
m.Set(test)
m.Get()
}
当Set()
, 执行时,它会m.ptr
正确打印 的内容。但是,当我们执行 a 时Get()
,它返回 nil。这看起来完全出乎我的意料。我正在使用 go 1.11.6
上述程序的输出是:
The pointer loaded is: 0x40c130
为什么这个指针值为零?
解决方案
因为该Set
方法有一个值接收器,所以当方法返回时,接收器值和对该值的任何更改都将被丢弃。通过使用指针接收器解决问题。
func (m *MapHolder) Set(myMap map[string]int64) { ... }
func (m *MapHolder) Get() map[string]int64 { ... }
该Get
方法还必须使用指针接收器来防止接收器参数副本上的数据竞争。
该Set
方法存储参数的地址myMap
,而不是m
in的地址main
。这可能是也可能不是问题,具体取决于应用程序如何使用MapHolder
.
推荐阅读
- react-native - expo-payments-stripe 中的 setOptionsAsync 应该将什么传递给 androidPayMode?
- swift - Swift firebase 子集合在初始化之外始终为空
- bash - 如何将带有变量值的参数添加到命令行?
- java - 使用预定义规则查找唯一实例的有效方法 (Java)
- azure - Owin/Azure 身份验证 - 为什么我无法访问母版页中的 User.Identity?
- asp.net-core - 如何将属性注释添加到我无法触及的自动生成的代码中
- mysql - mysql转储文件缺少表结构和数据
- javascript - 使用无限滚动时如何在 v-select 中设置初始值
- kubernetes - 使用带有提供的 python 庞大代码的 Nuclio 函数:可能吗?
- react-native - 如何禁用 ComponentWill... 来自依赖项的警告