首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >取消引用指针的类型断言是否是在go中写入内存?

取消引用指针的类型断言是否是在go中写入内存?
EN

Stack Overflow用户
提问于 2015-07-13 23:45:17
回答 1查看 228关注 0票数 2

go种族检测器以一种对我来说毫无意义的方式抱怨我的代码,但我想,种族检测器的作者比我更了解这一点。

我有个结论:

代码语言:javascript
复制
func(f *datastore.F) bool {
    a, ok := (*f).(*datastore.T)
    ...
}

作为参数传递给这个函数:

代码语言:javascript
复制
func GetFunc(f func(fid *datastore.F) bool) (*datastore.F, bool) {
    kvs.lock.RLock()
    defer kvs.lock.RUnlock()

    for _, v := range kvs.fs {
        if f(v) {
            return v, true
        }
    }
    return nil, false
}

这是另一个峡谷的相关部分:

代码语言:javascript
复制
for read := range [chan of datastore.F] {
    s.lock.Lock()
    s.fs[read.Fi()] = &read
    s.lock.Unlock()
}

kvs是这种类型的实例:

代码语言:javascript
复制
type kvstore struct {
    lock  sync.RWMutex
    fs map[datastore.Fi]*datastore.F
}

datastore.F是一个接口,*datastore.T实现了这个接口。

竞赛检测器抱怨关闭和另一个goroutine有一个数据竞争。另一个哥鲁丁写着,闭幕式写着。考虑到sync.RWMutex已经到位,我不知道这是如何发生冲突的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-14 00:00:07

取消引用指针的类型断言不会写入Go中的变量。

这段代码

代码语言:javascript
复制
for read := range [chan of datastore.F] {
   s.lock.Lock()
   s.fs[read.Fi()] = &read
   s.lock.Unlock()
}

将映射值设置为局部变量read的地址。变量read在for循环块之外有一个作用域,并且在循环中的每一次迭代中都进行修改。所有映射值都包含相同的指针,这可能不是您想要的。

闭包通过取消引用映射中的指针来读取变量read。竞争检测器抱怨是因为读取器(闭包)和写入器( for循环)之间没有同步。

要解决这个问题,在循环中声明一个新变量:

代码语言:javascript
复制
for read := range [chan of datastore.F] {
   read := read  // <-- Add this line
   s.lock.Lock()
   s.fs[read.Fi()] = &read
   s.lock.Unlock()
}

通过此更改,每个映射值指向一个唯一的变量,该变量只设置一次。

在Go中很少使用指向接口的指针。此问题的首选修复方法是将*datastore.F类型的所有用法更改为datastore.F。此更改消除了对变量read的跨goroutine边界的引用,并消除了不必要的间接级别。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31395316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档