为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 在 sync.Map 中操作对象

Golang 在 sync.Map 中操作对象

Go
犯罪嫌疑人X 2022-11-08 17:10:55
我正在尝试操作 golang sync.Map 的 sync.Map,但我在转换时遇到了一些问题。我有以下代码:func (cluster *Cluster) action(object1, object2 MyObject) {                value, _ := cluster.globalMap.LoadOrStore(object1.name, sync.Map{})                localMap := value.(sync.Map)                localMap.Store(object2.Name, object2)                                value2, _ := cluster.resourceInflight.Load(node.Name)                forComparison := value2.(sync.Map)                fmt.Println(localMap.Load(object2.Name))                fmt.Println(forComparison.Load(object2.Name))}{myObject  map[] map[]} true<nil> false我这样做是因为我希望保持 localMap 线程的内容安全。问题是我希望我的两个打印结果相同,因为“forComparison”应该指向与“localMap”相同的对象。但第二个结果为零。我怀疑问题出在将接口“值”转换为实际的“sync.Map”。但我不确定如何使用内联转换调用 .Store 方法。我考虑过将 localMap 存储在 cluster.globalMap 中,但这对我来说似乎不正确,因为它会破坏使用 localSyncMap 的全部意义并产生并发问题。关于我应该做什么的任何意见?
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

根据评论,问题是您正在复制sync.Map; 以下代码将失败(输出“未找到”-操场):


var sm sync.Map

var x interface{}

x = sm

sm2 := x.(sync.Map)

sm2.Store("test", "test")

result, ok := sm.Load("test")

if ok {

    fmt.Printf("Found: %s\n", result)

} else {

    fmt.Printf("Not found\n")

}

而使用指针按预期工作:


var sm sync.Map

var x interface{}

x = &sm

sm2 := x.(*sync.Map)

sm2.Store("test", "test")

result, ok := sm.Load("test")

if ok {

    fmt.Printf("Found: %s\n", result)

} else {

    fmt.Printf("Not found\n")

}

运行go vet可能会警告您其他问题(sync.Map包含 async.Mutex并且这些“首次使用后不得复制”)。


请注意 Sync.Map 状态的文档:


Map 类型是专门的。大多数代码应该使用普通的 Go 映射,使用单独的锁定或协调,以获得更好的类型安全性并更容易维护其他不变量以及映射内容。


查看完整回答
反对 回复 2022-11-08
  • 1 回答
  • 0 关注
  • 118 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信