Nocopy 最小的例子?
Nocopy minimal example?
我一直在尝试让 noCopy
指令为我自己的结构之一工作,但我无法让 go vet
检测到它。
我可以用它来检测 sync.WaitGroup
和 sync.Mutex
的复制,但不能检测我自己的结构。兽医来源中的 This test file 甚至不会触发我的 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
但是复制锁检测没有发现任何东西。
自 this discussion 1.4 以来 go vet
有什么变化吗?我是 运行 go version 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
检查 sync.Locker
接口,它也有一个 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
相关的一些更改:
我一直在尝试让 noCopy
指令为我自己的结构之一工作,但我无法让 go vet
检测到它。
我可以用它来检测 sync.WaitGroup
和 sync.Mutex
的复制,但不能检测我自己的结构。兽医来源中的 This test file 甚至不会触发我的 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
但是复制锁检测没有发现任何东西。
自 this discussion 1.4 以来 go vet
有什么变化吗?我是 运行 go version 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
检查 sync.Locker
接口,它也有一个 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
相关的一些更改: