没有复制最小的例子?

Fil*_*und 6 struct mutex go

我一直在尝试获取noCopy适用于我自己的结构之一的指令,但我无法go vet检测到它。

我可以让它检测sync.WaitGroup, 和 的复制sync.Mutex,但不能检测我自己的结构。兽医源中的这个测试文件甚至不会用我的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
Run Code Online (Sandbox Code Playgroud)

但复制锁检测没有发现任何东西。

go vet自从1.4版本的讨论以来,有什么变化吗?我在跑go version go1.11 darwin/amd64

icz*_*cza 4

首先,复制锁可以被正确检测到go vet。例子:

type My struct {
    l sync.Mutex
}
Run Code Online (Sandbox Code Playgroud)

用法:

func main() {
    m := My{}
    m2 := m
    fmt.Println(m2)
}
Run Code Online (Sandbox Code Playgroud)

运行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
Run Code Online (Sandbox Code Playgroud)

因此这两种情况(分配并传递给fmt.Println())都被检测到。

这也意味着在复制时使您的结构成为 vet 目标的最简单方法,只需添加一个类型为 的字段sync.Mutex。这是一个现成的解决方案,尽管它消耗内存(sync.Mutex不是零大小的结构)。是否使用这个互斥锁并不重要(我们在上面的示例中没有使用它)。

在您引用的讨论中,Rob Pike 建议创建一个类型:

type noCopy struct{}
func (*noCopy) Lock() {}
Run Code Online (Sandbox Code Playgroud)

并使用这种类型的字段(常规或嵌入)来标记结构不可复制(go vet如果发生这种情况请尖叫)。

我不知道这是否曾经有效,但目前还没有,因为go vet检查接口sync.Locker,它也有一个Unlock()方法:

type Locker interface {
        Lock()
        Unlock()
}
Run Code Online (Sandbox Code Playgroud)

因此,如果我们创建一个noCopy实现的类型sync.Locker(更准确地说是它的指针类型),那么它将起作用:

type noCopy struct{}

func (*noCopy) Lock()   {}
func (*noCopy) Unlock() {}

type By struct {
    noCopy noCopy
}
Run Code Online (Sandbox Code Playgroud)

测试它:

func main() {
    b := By{}
    b2 := b
    fmt.Println(b2)
}
Run Code Online (Sandbox Code Playgroud)

跑步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
Run Code Online (Sandbox Code Playgroud)

以下是与go vet和相关的一些更改noCopy

去1.7

去1.8