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