2012-08-14 138 views
4

如何将**T类型的变量转换为*unsafe.Pointer将** T转换为*不安全。指针

下面的例子将给出编译错误:如果我切换到(*unsafe.Pointer)(&ptr)&unsafe.Pointer(ptr)

cannot convert &ptr (type **s) to type *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)) 
} 

,我会得到这个编译错误:

cannot take the address of unsafe.Pointer(ptr)

诗篇。我选择sync/atomic作为例子,因为这是您实际上必须进行此类转换的一种情况。

编辑

一个不正确的解决办法是使用一个临时变量:

up := unsafe.Pointer(ptr) 
atomic.CompareAndSwapPointer(&up, ... 

虽然汇总,CAS只会掉什么是存储在up而不是ptr。这不是理想的结果,因为zeebo @#go-nuts指出。

回答

5

mcef @#去螺母张贴的答案如何转换** T:

(*unsafe.Pointer)(unsafe.Pointer(ptr)), where ptr is of type **T.

zeebo @#去螺母提供一个工作示例(这里发布许可):

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