在Go中将** T转换为* unsafe.Pointer

如何将类型的变量转换**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指出的那样,这不是理想的结果。


慕的地6264312
浏览 191回答 1
1回答

不负相思意

mcef @#go-nuts发布了如何转换** T的答案:(* unsafe.Pointer)(unsafe.Pointer(ptr)),其中ptr的类型为** T。zeebo @#go-nuts提供了一个工作示例(经许可在此处发布):package mainimport (    "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)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go