Golang—literal copies lock value from gzPool: sync.Pool contains sync.noCopy

mb6013c3565bec6 · · 839 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

[问题来源]<github.com/gin-contrib…)

源代码
func newGzipHandler(level int, options ...Option) *gzipHandler {
 var gzPool sync.Pool
 gzPool.New = func() interface{} {
  gz, err := gzip.NewWriterLevel(ioutil.Discard, level)
  if err != nil {
   panic(err)
  }
  return gz
 }
 handler := &gzipHandler{
  Options: DefaultOptions,
  gzPool: gzPool,
 }
 for _, setter := range options {
  setter(handler.Options)
 }
 return handler
}复制代码
修改后的代码
func newGzipHandler(level int, options ...Option) *gzipHandler {
 handler := &gzipHandler{
  Options: DefaultOptions,
  gzPool: sync.Pool{
   New: func() interface{} {
    gz, err := gzip.NewWriterLevel(ioutil.Discard, level)
    if err != nil {
     panic(err)
    }
    return gz
   },
  },
 }
 for _, setter := range options {
  setter(handler.Options)
 }
 return handler
}复制代码

golang中是如何实现禁止拷贝?

阅读sync的源码发现有以下代码,可以看到如果不希望结构体被复制,可以嵌入一个noCopy结构体来实现

// noCopy may be embedded into structs which must not be copied// after the first use.//// See https://golang.org/issues/8005#issuecomment-190753527// for details.type noCopy struct{}// Lock is a no-op used by -copylocks checker from `go vet`.func (*noCopy) Lock()   {}func (*noCopy) Unlock() {}// A Pool must not be copied after first use.type Pool struct {
  noCopy noCopy
  ...
}复制代码

验证嵌入noCopy是否可用

package nocopytype noCopy struct{}func (*noCopy) Lock()   {}func (*noCopy) Unlock() {}type UserInfo struct {
   noCopy  noCopy
   Name    string
   Address string}type Person struct {
    user UserInfo
}func TestNoCopy(t *testing.T) {
    userinfo := UserInfo{Name: "ouyangjun", Address: "北京"}
    per := Person{
        User: userinfo,
    }
    log.Println(&per)
}


bash-4.3# go vet ./
# github.com/oyjjpp/script/nocopy
./nocopy_test.go:11:9: literal copies lock value from userinfo: github.com/oyjjpp/script/nocopy.UserInfo contains github.com/oyjjpp/script/nocopy.noCopy复制代码

通过vet检查发现确实有标题所示的提示literal copies lock value from userinfo

golang源码使用的位置(go1.15.6)

[root@d589ba887dc5 src]# grep -Ri "noCopy" ./sync
./sync/cond.go:	noCopy noCopy
./sync/cond.go:// noCopy may be embedded into structs which must not be copied./sync/cond.go:type noCopy struct{}
./sync/cond.go:func (*noCopy) Lock()   {}
./sync/cond.go:func (*noCopy) Unlock() {}
./sync/waitgroup.go:	noCopy noCopy
./sync/pool.go:	noCopy noCopy复制代码

总结

如果golang中希望实现的数据结构不能进行copy,就可以实现noCopy结构,在使用上使用指针传递保证全局唯一


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

839 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传