英文:
Convert **T to *unsafe.Pointer in Go
问题
如何将类型为**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所指出的。
英文:
How do I convert a variable of type **T
to *unsafe.Pointer
?
The example below will give the compilation error:
> 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))
}
If I switch (*unsafe.Pointer)(&ptr)
to &unsafe.Pointer(ptr)
, I will get this compilation error:
> cannot take the address of unsafe.Pointer(ptr)
Ps. I choose to make an example with sync/atomic
because that is one situation where you actually have to do such a conversion.
Edit
One incorrect solution would be to use a temporary variable:
up := unsafe.Pointer(ptr)
atomic.CompareAndSwapPointer(&up, ...
While it compiles, the CAS will only swap what is stored in up
and not in ptr
. This is not the desired result, as zeebo@#go-nuts pointed out.
答案1
得分: 7
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)
}
英文:
mcef@#go-nuts posted the answer how to convert **T:
> (*unsafe.Pointer)(unsafe.Pointer(ptr)), where ptr is of type **T.
zeebo@#go-nuts provided a working example (posted here with permission):
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论