golang判断一个对象是否被拷贝

本文深入探讨了GoLang中的防拷贝机制,通过使用atomic包和unsafe包,实现了一个防拷贝结构TEST,该结构在创建时会记录其内存地址,并在每次调用检查函数时对比地址,若地址发生变化,则说明对象已被拷贝,从而触发panic。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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保存的地址是否一致。 不一致说明,地址发生了变化, 变量被拷贝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值