如何将**T
类型的变量转换为*unsafe.Pointer
?
以下示例将给出编译错误:
无法将& ptr(类型** s)转换为* unsafe.Pointer
类型
package main
import (
"sync/atomic"
"unsafe"
)
type s struct {
value int
}
func main(){
var ptr *s
a := &s{42}
old := ptr
atomic.CompareAndSwapPointer(
(*unsafe.Pointer)(&ptr), // &unsafe.Pointer(ptr)
unsafe.Pointer(old),
unsafe.Pointer(a))
}
如果我将(*unsafe.Pointer)(&ptr)
切换为&unsafe.Pointer(ptr)
,我将收到此编译错误:
不能取unsafe.Pointer(ptr)的地址
聚苯乙烯。我选择使用sync/atomic
作为示例,因为这是您实际需要进行此类转换的一种情况。
修改
一个不正确的解决方案是使用临时变量:
up := unsafe.Pointer(ptr)
atomic.CompareAndSwapPointer(&up, ...
在编译时,CAS只会交换存储在up
而不是ptr
中的内容。这不是理想的结果,正如zeebo @#go-nuts指出的那样。
答案 0 :(得分:6)
mcef @#go-nuts发布了答案如何转换** T:
(* unsafe.Pointer)(unsafe.Pointer(ptr)),其中ptr的类型为** T.
zeebo @#go-nuts提供了一个工作示例(经过许可发布):
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
type T struct {
value int
}
func Swap(dest **T, old, new *T) bool {
udest := (*unsafe.Pointer)(unsafe.Pointer(dest))
return atomic.CompareAndSwapPointer(udest,
unsafe.Pointer(old),
unsafe.Pointer(new),
)
}
func main() {
x := &T{42}
n := &T{50}
fmt.Println(*x, *n)
p := x
Swap(&x, p, n)
fmt.Println(*x, *n)
}