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

时间:2012-08-14 21:07:28

标签: pointers type-conversion go unsafe-pointers

如何将**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指出的那样。

1 个答案:

答案 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)
}