如何比较Go中的指针?

时间:2017-08-22 13:26:35

标签: pointers go comparison

我正在构建一些测试代码,并尝试将指针与<>运算符进行比较。我的目标是将元素排序为平衡的树结构(由我实现)。为此,我需要快速,通用的比较。遵循良好的旧C / C ++风俗习惯,我目前的想法是( ......在撰写本文时),用指针地址对它们进行比较。

但是,正如我发现的那样,它不起作用。来源

if (&(a.val) < &(b.val)) {

给出编译错误

  

./ pointer.go:40:无效操作:&amp; a.val&lt; &amp; b.val(运算符&lt;未在指针上定义)

abval为(安全)指针成员的结构。

是否可以比较go中的安全指针?怎么样?

是否保证指针的顺序保持不变? (例如,我可以想象一些GC技巧,它也会重新排序数据。)

1 个答案:

答案 0 :(得分:4)

  

是否保证指针的顺序保持不变? (对于   例如,我可以想象一些GC技巧,它也会重新排序数据。)

在回答你问题的这一部分时,它看起来并不像。请参阅下面的pkg unsafe链接。

如果你想要指针的内存地址,请尝试不安全的包:

https://golang.org/pkg/unsafe/#Pointer

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var a,b int
    var pa,pb *int
    pa = &a
    pb = &b

    //var c int
    //pa = &c

    if uintptr(unsafe.Pointer(pa)) < uintptr(unsafe.Pointer(pb)) {
      fmt.Printf("a:%p > b:%p",pa,pb)   
    } else {
      fmt.Printf("b:%p > a:%p",pb,pa)
    }

}

这将使您获得任意指针类型,然后获得该指针的当前内存地址(如printf所示)。请注意那里的警告,你不能依赖这个地址:

  

将指针转换为uintptr会产生内存地址   值指向,作为整数。这种uintptr的通常用途是   打印它。将uintptr转换回Pointer无效   一般。 uintptr是整数,而不是引用。转换一个   指向uintptr的指针会创建一个没有指针的整数值   语义。即使uintptr保存某个对象的地址,也就是   垃圾收集器不会更新该对象的uintptr值   移动,uintptr也不会阻止对象被回收。

这会绕过Go类型系统和内存安全性,因此它不安全,您可能不想这样做,除非您只是在尝试。我无法想象在测试中做到这一点的理由,但是如果你想确保阅读整篇文档并且非常确定你知道你正在做的事情会按预期工作。