我想检查两个引用是否指向同一个对象。我似乎可以简单地使用
if ($ref1 == $ref2) {
# cheap numeric compare of references
print "refs 1 and 2 refer to the same thing\n";
}
如perlref
中所述,但我依旧记得看到为同一目的使用某些功能。有什么理由我不应该使用简单的数字相等测试吗?
注意我只想知道引用是否指向完全相同的对象。我不想找到比较对象内容的方法。
答案 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
快得多,更不用说比任何深度比较。
具有直接或间接重载==
运算符的对象可能会出于自己的目的而篡改测试。但如果它 这样做,你甚至可能更喜欢它的中介答案。
您采取的方法可能取决于您对对象类的了解。适用于一般情况的方法对于特定情况并不总是最佳的。你对事物的了解越多,你就可以越多地优化它 - 反过来也是如此。
因此,如果您知道您没有使用具有适用重载的类,则没有理由在非内置库函数中运行,并且没有理由不这样做。如果你不知道重载,或者你知道它并且不希望它应用,那么也许采取缓慢的方法。
只要您了解重载问题,就认为一种方法是正确的而另一种方法是错误的,这是错误的。每个都有它的目的。如果做你正在做的事总是错的,那么这个操作要么被禁止,要么至少被警告过。
您会注意到不如此标记。