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