我一直在尝试获取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。
首先,复制锁可以被正确检测到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:
| 归档时间: |
|
| 查看次数: |
3077 次 |
| 最近记录: |