[问题来源]<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结构,在使用上使用指针传递保证全局唯一