Go类型与指针语法解析,atomic.CompareAndSwapInt32语法疑问
Go语言类型、指针语法及自旋锁代码解析
示例代码
package listing12_9 import ( "runtime" "sync" "sync/atomic" ) type SpinLock int32 func (s *SpinLock) Lock() { for !atomic.CompareAndSwapInt32((*int32)(s), 0, 1) { runtime.Gosched() } } func (s *SpinLock) Unlock() { atomic.StoreInt32((*int32)(s), 0) } func NewSpinLock() sync.Locker { var lock SpinLock return &lock }
一、Go语言的类型与指针语法
1. 自定义类型
Go通过type关键字基于已有类型创建自定义类型,比如代码里的type SpinLock int32,是把基础类型int32包装成新的SpinLock类型。这么做的核心目的是给这个类型绑定专属方法(比如Lock和Unlock),让它拥有特定的行为逻辑。
2. 指针相关语法
- 指针类型:用
*T表示,代表指向类型T的指针,存储的是变量的内存地址。比如*SpinLock就是指向SpinLock实例的指针。 - 取地址符
&:用来获取变量的内存地址,比如&lock就是拿到lock这个SpinLock变量的地址,得到*SpinLock类型的值。 - 显式类型转换:Go是强类型语言,不同类型之间必须显式转换。比如把
*SpinLock转成*int32,需要用(*int32)(s)这种写法,告诉编译器把目标变量的内存当成指定类型来处理。
二、atomic.CompareAndSwapInt32((*int32)(s), 0, 1)的解析
1. 整体作用
atomic.CompareAndSwapInt32是sync/atomic包提供的原子操作函数,核心逻辑是比较并交换:
- 第一个参数是要操作的
int32类型变量的指针; - 第二个参数是预期的旧值;
- 第三个参数是要设置的新值;
- 返回布尔值:如果目标内存地址的当前值等于预期旧值,就把它替换成新值,返回
true;否则不做修改,返回false。
在自旋锁的Lock方法里,这个函数被放在for循环中,直到交换成功才退出,实现了“自旋等待锁”的逻辑——只要没抢到锁(交换失败),就一直尝试,同时调用runtime.Gosched()让出CPU时间片,避免占用过多资源。
2. (*int32)和s的含义
s:是Lock方法的接收者,类型为*SpinLock,也就是当前要操作的自旋锁实例的指针,代表我们要修改的那个锁对象。(*int32):这是显式类型转换。因为SpinLock是基于int32定义的自定义类型,而atomic.CompareAndSwapInt32要求第一个参数必须是*int32类型,所以需要把*SpinLock类型的s转换成*int32类型。这种转换是安全的,因为SpinLock的底层存储就是int32,转换后只是让编译器以int32的视角去操作这块内存。
内容的提问来源于stack exchange,提问作者fuyou001
相关产品推荐
相关产品推荐

