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中,源代码甚至不会触发my
go 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。很好的挖掘,谢谢你的回答。