Go 定义类型上的原子操作

Go 定义类型上的原子操作,go,Go,如果我定义一种新类型的“状态”,如下所示: type State int32 类型“State”的值是否可以应用于原子操作,如“atomic.StoreInt32()” 若否,原因为何 如果可以,是否可以按以下方式应用 func SetAndGet(s State, n State) State { si := int32(s) ni := int32(n) return State(atomic.SwapInt32(&si, ni)) } 更新: 根据@i

如果我定义一种新类型的“状态”,如下所示:

type State int32
类型“State”的值是否可以应用于原子操作,如“atomic.StoreInt32()”

若否,原因为何

如果可以,是否可以按以下方式应用

func SetAndGet(s State, n State) State {
    si := int32(s)
    ni := int32(n)
    return State(atomic.SwapInt32(&si, ni))
}

更新:

根据@icza的回答,代码修改如下

func SetAndGetState(s *State, n State) State {
    return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
func SetAndGetInt(s *int32, n int32) State {
    return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
var s1 State = 1
var i1 int32 = 1
SetAndGetState(&s1, 2)
SetAndGetInt(&i1, 2)
我试过我和@icza的密码。他们都成功了。“State”的结果似乎与int32相同。我想知道的是:
在高并发情况下,原子操作对定义类型“State”的并发效果是否与对“int32”的并发效果相同

原子操作通常在变量上执行

调用函数时,将复制传递的值。没有理由对仅由函数使用的局部变量(函数参数)执行原子操作

您可能希望执行原子操作,例如对全局变量执行原子操作。要想做到这一点,您必须传递它的地址(传递它的值只是复制它)

而且,您不能创建所传递指针的本地副本(也不能创建指向的值),必须将获得的地址直接传递到
atomic.SwapInt32()
。要做到这一点,只需将
*State
指针转换为
*int32
。这是可能的,因为
State
int32
作为其基础类型:

func SetAndGet(s *State, n State) State {
    return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
测试它:

var s State

func main() {
    fmt.Println(SetAndGet(&s, 1))
    fmt.Println(SetAndGet(&s, 2))
    fmt.Println(SetAndGet(&s, 3))
}
输出(在上尝试):


使用上述解决方案,您可以获得与使用
int32
而不是
State
时相同的并发保证,原子操作通常对变量执行

调用函数时,将复制传递的值。没有理由对仅由函数使用的局部变量(函数参数)执行原子操作

您可能希望执行原子操作,例如对全局变量执行原子操作。要想做到这一点,您必须传递它的地址(传递它的值只是复制它)

而且,您不能创建所传递指针的本地副本(也不能创建指向的值),必须将获得的地址直接传递到
atomic.SwapInt32()
。要做到这一点,只需将
*State
指针转换为
*int32
。这是可能的,因为
State
int32
作为其基础类型:

func SetAndGet(s *State, n State) State {
    return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
测试它:

var s State

func main() {
    fmt.Println(SetAndGet(&s, 1))
    fmt.Println(SetAndGet(&s, 2))
    fmt.Println(SetAndGet(&s, 3))
}
输出(在上尝试):


使用上述解决方案,您可以获得与使用
int32
而不是
State

相同的并发性保证。尝试时会发生什么?只需实现这三行代码并测试它们,然后继续问,可能会快得多?“是”是答案的缩写。对不起。我已经添加了更多我想知道的细节。我测试的结果似乎是正确的。但我想知道,在高并发情况下,当遇到原子操作时,是否可以使用定义的类型“State”而不是“int32”。如果您尝试,会发生什么?只实现这三行代码并测试它们可能会快得多,然后继续问?“是”是答案的缩写。对不起。我已经添加了更多我想知道的细节。我测试的结果似乎是正确的。但我想知道,在高并发情况下,当遇到原子操作时,是否可以使用定义的类型“State”来代替“int32”。这是否意味着在高并发情况下,原子操作对定义的类型“State”的并发效果与对“int32”的并发效果相同?@JunfeiHu是的,您将获得与使用
int32
相同的并发保证。这是否意味着,在高并发情况下,原子操作对定义类型“State”的并发效果与对“int32”的并发效果相同?@JunfeiHu是的,您将获得与使用
int32
相同的并发保证。