我应该如何比较Perl参考?

时间:2010-10-31 16:44:19

标签: perl reference compare

我想检查两个引用是否指向同一个对象。我似乎可以简单地使用

if ($ref1 == $ref2) { 
 # cheap numeric compare of references
 print "refs 1 and 2 refer to the same thing\n";
}

perlref中所述,但我依旧记得看到为同一目的使用某些功能。有什么理由我不应该使用简单的数字相等测试吗?

注意我只想知道引用是否指向完全相同的对象。我不想找到比较对象内容的方法。

3 个答案:

答案 0 :(得分:25)

默认情况下,引用将编号为其地址。这些引用地址对于每个引用都是唯一的,因此它通常可用于相等性检查。

但是,在您展示的代码段中,您首先必须确保$ref1$ref2实际上都是引用。否则,由于包含引用地址的常规标量,您可能会得到不正确的结果。

此外,没有什么可以保证引用numify到它们的地址。例如,对象可以使用重载来影响它们在不同上下文中返回的值。

比直接比较引用以获得数字相等性更简单的方法是使用Scalar::Util提供的refaddr函数,确保双方实际上都是引用。

答案 1 :(得分:16)

您正在寻找的函数是来自Scalar::Util的refaddr(在确保被比较的值确实是引用之后):

use Scalar::Util 'refaddr';

if ($obj1 and ref($obj1) and $obj2 and ref($obj2) and
    refaddr($obj1) == refaddr($obj2))
{
    # objects are the same...
}

答案 2 :(得分:7)

我必须假设你的#comment关于如何便宜(=快)平等测试是有原因的。鉴于此,你应该继续使用廉价的平等测试。它非常快,比eq快得多,更不用说比任何深度比较。

具有直接或间接重载==运算符的对象可能会出于自己的目的而篡改测试。但如果它 这样做,你甚至可能更喜欢它的中介答案。

您采取的方法可能取决于您对对象类的了解。适用于一般情况的方法对于特定情况并不总是最佳的。你对事物的了解越多,你就可以越多地优化它 - 反过来也是如此。

因此,如果您知道您没有使用具有适用重载的类,则没有理由在非内置库函数中运行,并且没有理由不这样做。如果你不知道重载,或者你知道它并且不希望它应用,那么也许采取缓慢的方法。

只要您了解重载问题,就认为一种方法是正确的而另一种方法是错误的,这是错误的。每个都有它的目的。如果做你正在做的事总是错的,那么这个操作要么被禁止,要么至少被警告过。

您会注意到如此标记。