Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

精通 Ruby 相等性:自訂 == 實作比較物件

相等性意味著兩件事是一樣的。在 Ruby,我們比較物件和它們的值來發現它們是否為同一個物件。

問題是……

如何在 Ruby 比較兩件事?

像這樣:

 1 == 1 # true 

你可能已經熟悉這個……

但你知道 == 是個方法,不只是語法嗎?

含意很大。

你可以在自己的類別實作這個方法讓它們更強大。這就是你在這篇文章將學到的!

什麼讓兩個物件相同?

你可以這樣比較兩個字串:

 "foo" == "foo" 

如果 單字和字元 相同,它們就相等。

運算式回傳 true。

這能動是因為 String 類別實作了 ==(兩個等號)方法,知道如何比較字串。

但如果 String 沒實作 == 呢?

那麼 Ruby 會用 Object 的 == 實作,預設測試物件身分,而不是物件內容。

例子:

 Object.new == Object.new # false String.new == String.new # true 

Object 回傳 false 的原因是兩個新物件有不同的 object id。

對於 String,因為它基於內容比較,兩個新字串內容相同(都是空的)所以回傳 true。

實作相等性

現在用你剛學到的讓你自己的類別更強大,能夠比較它們。

多虧了 == 方法……

你可以精確定義兩個你自己類別的實例何時相等。

例子:

 class Product attr_reader :name, :price def initialize(name, price) @name, @price = name, price end def ==(other) self.name == other.name && self.price == other.price end end p1 = Product.new('book', 49) p2 = Product.new('book', 49) p1 == p2 # true 

== 方法說名稱和價格都必須相同,兩個 Product 物件才視為相等。

記住:

如果你不實作這方法(或用 Comparable 模組,我在我的 Ruby 書解釋)兩個物件會用它們的 object id 比較,而不是值。

也應該提到如果你用 Struct 它已經幫你實作 == 了。

那三個等號 (===) 呢?

你可能想既然 == 是方法,=== 也是方法嗎?答案是 yes 🙂

那麼兩者差別是什麼?

在 Javascript 有明確差別,== 會嘗試轉換物件類型使其相同如果不一樣(1 vs '1')。而 === 是「嚴格」相等。

但在 Ruby 沒有這種事。=== 意思取決於實作它的類別。

在許多情況下它只是 == 的別名。

像在 String 和 Object。

這裡有內建類別給 === 特殊含義的表格:

Class Meaning
Range 如果 obj 是 range 的元素回傳 true,否則 false。
Regexp 對字串比對 regexp。
Module 如果 obj 是 mod 的實例或 mod 後代的實例回傳 true。
Proc 用 obj 作為 proc 參數調用區塊,像 Proc#call。允許 proc 物件成為 case 陳述式 when 子句的目標。

結論

這篇文章你學到如何實作 == 方法讓類別更強大。也學到 == 和 === 的差別。

別忘了 分享這篇文章 讓更多人看到 🙂