我应该如何比较Perl参考?

Dav*_*d B 27 perl compare reference

我想检查两个引用是否指向同一个对象.看来我可以简单地使用

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

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

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

raf*_*afl 25

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

然而,在你表现出的片段中,你首先要确保两个$ref1$ref2实际上的引用.否则,由于包含引用地址的常规标量,您可能会得到不正确的结果.

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

比直接比较引用以获得数字相等性更为可靠的方法是在确保双方实际上都是引用之后使用由refaddr提供的函数Scalar::Util.

  • 如果你正在使用一个类,其对象有一个nummification(`0 +`)重载,或者一个`==`重载(也许是通过`<=>`),那么你实际上可能*想要*截获它,自定义的平等感.在不提及这些考虑因素的情况下做出一揽子陈述似乎过于简单.也就是说,我想不出很多场景,其中模块功能所采用的代码路径将是您尝试从最后一点性能中获取的关键路径.但如果它是,当然你会想要使用正常的`==`. (2认同)

Eth*_*her 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...
}
Run Code Online (Sandbox Code Playgroud)

  • 幸运的是,由于List-Util发行版和它包含的Scalar :: Util模块是核心模块,核心是用C编译器构建的,几乎每个人都可以使用C版的Scalar :: Util :: refaddr,几乎只有一个标志检查和解除引用. (4认同)
  • `cpan/List-Util/lib/Scalar/Util/PP.pm`的refaddr()函数采取非常措施来判断指示对象的实际地址,只有blessed()函数才能找到包名称. (2认同)
  • +1是提供代码段的唯一答案.你实际上可以保存2个检查,因为`ref($ obj)`的计算结果为false,即使`$ obj`是`undef`.那么也许摆脱`$ obj1`和`$ obj2`条件? (2认同)

tch*_*ist 7

我必须假设你#comment的平等测试是多么便宜(=快)是有原因的.鉴于此,你应该继续使用廉价的平等测试.这是非常快,远远快eq,更何况比任何形式的深比较.

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

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

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

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

你会注意到它没有那么明显.

  • @friedo:如果你认为我是对的,那么知道你认为我是对的就足够了.(即便如此,如果有一个值得强调的特定点,"+1 for ..."评论相当普遍.)如果你认为我错了,我想知道*为什么*你认为我错了所以我可以澄清我的陈述,反驳你的反对意见,甚至可能(恐怖的恐怖)意识到你的异议是准确的,并从他们那里学到一些东西.这就是为什么我至少要对downvotes发表评论,但不关心任何一种方式. (3认同)
  • 你会认为所有的反对者都会有勇气说出他们认为我说的是错误的内容。但他们没有。很明显,他们更喜欢匿名隐藏的锅贴而不是理性的话语。如果你不能证明你的投票是合理的,也许你不应该去投票。 (2认同)
  • 我对你发布的内容没有任何问题(并没有downvote),但我认为有趣的是许多海报要求对downvotes进行解释,而不是对upvotes进行解释.我不花时间证明我每天给出的20多个赞成票. (2认同)