我试图在Go中实现XOR链接列表,我必须存储XORed地址。在C / C ++中,它非常简单
(*struct_type)(([unsigned] int)nodeA ^ ([unsigned] int)nodeB)
我在Go尝试了类似的方法。我有一个名为Node的结构,有两个节点nodeA和nodeB。为此,我尝试了以下方法:
*Node(uint(nodeA) ^ uint(nodeB))
这给了我一个错误说,不能将类型Node转换为uint。 我尝试过的另一种方式,我确信无法工作,是
nodeA ^ nodeB
有没有办法将地址解析为int类型,对它们进行异或,然后将它们重新解析为Node地址?或者Go为我提供了一个我不知道的简单解决方案吗?
答案 0 :(得分:3)
您无法在Go中实施XOR链接列表。 Go垃圾收集器(GC)使用指针值来跟踪正在使用的内存。如果您修改指针值,GC将无法工作。
答案 1 :(得分:2)
使用unsafe.Pointer进行指针运算:
a := &T{}
b := &T{}
x := uintptr(unsafe.Pointer(a)) ^ uintptr(unsafe.Pointer(b))
y := (*T)(unsafe.Pointer(uintptr(unsafe.Pointer(a)) ^ x))
fmt.Println(b == y) // prints true
GC使用指针来跟踪内存。如果代码被重写为
a := &T{}
b := &T{}
x := uintptr(unsafe.Pointer(a)) ^ uintptr(unsafe.Pointer(b))
b = nil // clear all pointers to struct
b = (*T)(unsafe.Pointer(uintptr(unsafe.Pointer(a)) ^ x))
然后GC可以在最后一次分配给b
之前收集b
指向的结构。
由于GC可以收集元素,因此无法在Go中实现安全的XOR列表。
不要这样做。
答案 2 :(得分:0)
感谢您指出Go不支持指针算法。我做了一个快速研究,发现并使用了 usafe 包Go提供以防万一"不安全"在需要的工作。我用以下几行代码解决了这个问题:
a := unsafe.Pointer(nodeA)
b := unsafe.Pointer(nodeB)
return (*Node)(unsafe.Pointer(uintptr(a) ^ uintptr(b)))
docs到不安全的包裹。