package main
import (
"sync/atomic"
"unsafe"
)
type noCopy struct{}
// Lock is a no-op used by -copylocks checker from `go vet`.
func (*noCopy) Lock() {}
type TEST struct {
name string
noCopy noCopy
copy copyChecker
}
type copyChecker uintptr
func (c *copyChecker) check() {
// 如果 c != 当前地址
if uintptr(*c) != uintptr(unsafe.Pointer(c)) &&
// 第一次 c = 0, 则 c = 当前地址, 返回true; 否则,如果 c != 0, 返回false
!atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) &&
//如果 c != 当前地址
uintptr(*c) != uintptr(unsafe.Pointer(c)) {
//三个条件都满足,说明对象被拷贝
panic("object is copied")
}
}
func NewTest(name string) *TEST {
return &TEST{name:name}
}
func (t *TEST) copyCheck(){
t.copy.check()
}
func main(){
a := NewTest("aa")
a.copyCheck()
println(a.copy)
b := *a
println(&b)
println(b.copy)
b.copyCheck()
}
来自于 golang源码 src/sync/cond.go 条件变量的实现。
变量第一次生成的时候, 将当前地址保存到copy变量中。
变量被拷贝的时候,再次检查 当前的地址与之前copy保存的地址是否一致。 不一致说明,地址发生了变化, 变量被拷贝。