Go Nocopy最小示例?
我一直试图获得一个Go Nocopy最小示例?,go,struct,mutex,Go,Struct,Mutex,我一直试图获得一个noCopy指令来为我自己的结构之一工作,但我无法获得go-vet来检测它 我可以让它检测sync.WaitGroup和sync.Mutex的复制,但不能检测我自己的结构。在vet中,源代码甚至不会触发mygo vet 或者,它会发现一些错误: # command-line-arguments ./govet.go:56:6: no new variables on left side of := ./govet.go:110:17: unsafe.Sizeof(mu) eva
noCopy
指令来为我自己的结构之一工作,但我无法获得go-vet
来检测它
我可以让它检测sync.WaitGroup
和sync.Mutex
的复制,但不能检测我自己的结构。在vet中,源代码甚至不会触发mygo vet
或者,它会发现一些错误:
# command-line-arguments
./govet.go:56:6: no new variables on left side of :=
./govet.go:110:17: unsafe.Sizeof(mu) evaluated but not used
./govet.go:111:18: unsafe.Sizeof(mu) evaluated but not used
./govet.go:112:10: unsafe.Sizeof(mu) evaluated but not used
但是复制锁检测没有发现任何东西
从1.4开始,
go vet
有什么变化吗?我正在运行go1.11 darwin/amd64版本。首先,复制锁被go vet正确检测到。例如:
type My struct {
l sync.Mutex
}
用法:
func main() {
m := My{}
m2 := m
fmt.Println(m2)
}
运行<代码>go vet,输出为:
./play.go:25: assignment copies lock value to m2: main.My contains sync.Mutex
./play.go:26: call of fmt.Println copies lock value: main.My contains sync.Mutex
因此,两种情况(分配和传递到fmt.Println()
)都被检测到
这也意味着在复制时使结构成为vet目标的最简单方法是添加一个类型为sync.Mutex
的字段。这是一个现成的解决方案,尽管它会消耗内存(sync.Mutex
不是零大小的结构)。不管您是否使用这个互斥锁(在上面的示例中我们没有使用它)
在您提到的讨论中,Rob Pike建议创建一个类型:
type noCopy struct{}
func (*noCopy) Lock() {}
并使用此类型的字段(常规或嵌入式)来标记结构不可复制(如果发生这种情况,请使go-vet
尖叫)
我不知道这是否有效,但目前没有,因为go-vet
检查接口,该接口也有Unlock()
方法:
type Locker interface {
Lock()
Unlock()
}
因此,如果我们创建一个实现sync.Locker
(更准确地说是它的指针类型)的noCopy
类型,它将工作:
type noCopy struct{}
func (*noCopy) Lock() {}
func (*noCopy) Unlock() {}
type By struct {
noCopy noCopy
}
测试它:
func main() {
b := By{}
b2 := b
fmt.Println(b2)
}
运行go-vet
:
./play.go:29: assignment copies lock value to b2: main.By contains main.noCopy
./play.go:30: call of fmt.Println copies lock value: main.By contains main.noCopy
以下是与go vet
和noCopy
相关的一些更改:
我模糊地记得还有一个
解锁接口。如果是这样的话,也许他们将两者合并,并将额外的功能添加到Locker
?@FilipHaglund我怀疑他们删除了Unlocker
:它目前不在标准库中,删除它将导致向后不兼容(从而破坏Go 1的兼容性承诺)。我添加了一些关于govet
和nocopy
的链接。也许这个界面以前不公开?Idk。很好的挖掘,谢谢你的回答。