2010-10-31 43 views
24

我想檢查兩個引用是否指向同一個對象。看來我可以簡單地使用我應該如何比較Perl引用?

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

perlref提及,但我依稀記得看到了同樣的目的而使用的一些功能。我有什麼理由不應該使用簡單的數字相等性測試?

注意我只想知道引用是否指向完全相同的對象。我不想找到一種方法來比較對象的內容。

回答

23

參考,默認情況下,numify他們的地址。這些參考地址對於每個參考都是唯一的,所以它通常可用於平等檢查。

但是,在您展示的代碼段中,首先必須確保$ref1$ref2實際上都是引用。否則,由於包含引用地址的常規標量,您可能會得到不正確的結果。

此外,沒有什麼保證引用numify到他們的地址。例如,對象可以使用重載來影響它們在不同情況下返回的價值。

比確定數值相等時直接比較引用更穩定的方法是使用Scalar::Util提供的refaddr函數,確保雙方實際上都是引用。

+1

如果您使用的對象有nummification('0 +')重載或'=='重載的類(可能通過'<=>'),那麼您可能實際上*希望*截獲它的自定義平等感。在沒有提及這些考慮因素的情況下作一攬子發言似乎過於容易。也就是說,我不能想到很多情況下,模塊函數所採用的代碼路徑將成爲您試圖扭曲性能的關鍵路徑。但是,如果它是,當然你會想要使用正常的'=='。 – tchrist 2010-10-31 17:09:51

+0

同意。這就是爲什麼你的回答從我這裏得到讚揚提到這一點。有很多情況下,人們可能想要比較事物是否平等,並且應該爲每種情況分別考慮使用的平等類型。不過,這個問題很具體,因此得到了具體的答案。 – rafl 2010-10-31 17:14:41

+0

它也值得一個具體的答案。這就是爲什麼你得到我的讚賞。 ☺ – tchrist 2010-10-31 22:30:12

15

你正在尋找的功能是從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

'cpan/List-Util/lib/Scalar/Util/PP.pm'的refaddr()函數用來預測指示對象的真實地址所採取的非常措施,只有通過blessed()函數的度量來超越包裹名字。 – tchrist 2010-10-31 17:03:27

+4

幸運的是,由於List-Util分佈以及它包含的Scalar :: Util模塊都是核心模塊,而且核心是使用C編譯器構建的,幾乎每個人都可以使用Scalar的C版本: Util :: refaddr,這幾乎只有一個標誌檢查和一個取消引用。 – rafl 2010-10-31 17:11:55

+0

在mktables代碼中實際上有一個測試,它是否是一個快速的Scalar :: Util或不是。我應該記得它可能只是一個C通話。 – tchrist 2010-10-31 22:31:11

7

我必須假設你的#comment關於平等測試是多麼便宜(=快)是有原因的。鑑於此,您應該繼續使用便宜的平等測試。這是很快快,比eq快得多,更不用說比任何形式的深度比較。

有可能直接或間接超載==運算符的對象可能爲了自己的目的篡奪測試。但如果它這樣做,你甚至可能更喜歡它的中介答案。

你採取的方法可能取決於你對對象的類的瞭解。適用於一般情況的方法對於特定情況並不總是最佳的。你對某件事瞭解得越多,就越能優化它 - 反之亦然。

所以,如果你知道,你沒有使用一個適用的重載類,沒有理由去牽扯一個非內置的庫函數,公平的理由不是。如果你不知道超載,或者你知道它並且不希望它適用,那麼也許採取緩慢的方法。

只要你知道瞭解重載問題,認爲一種方法是正確的,另一種錯誤是錯誤的。每個都有其目的。如果你做的事情總是錯誤的,那麼這個操作將被禁止或者至少受到警告。

你會注意到它是而不是如此標記。

+1

你會認爲所有的選民都會有膽量說出他們認爲我說的是錯的是什麼。但他們沒有。所以顯然他們更喜歡匿名的隱藏的鏡頭來推理話語。如果你不能證明你的投票是正確的,也許你不應該這樣做。 – tchrist 2010-10-31 18:14:17

+1

我對你發佈的內容沒有任何問題(並沒有downvote),但我認爲有趣的是,許多海報需要downvotes的解釋,但不支持upvotes。我沒有花時間來證明我每天給予的20多個讚美詞。 – friedo 2010-10-31 18:23:06

+3

@friedo:如果你認爲我是對的,知道你認爲我是對的就足夠了。 (即使如此,如果有一個特別值得強調的地方,「+1 ...」的評論是相當普遍的。)如果你認爲我錯了,我想知道*爲什麼*你認爲我錯了,所以我可以澄清我的陳述,駁斥你的反對意見,甚至可能(恐怖恐怖)意識到你的異議是準確的,並從中學到一些東西。這就是爲什麼我至少希望評論downvotes,但不關心upvotes的任何方式。 – 2010-11-01 09:38:18