“==” 最常見的相等性判斷
“==” 使用最頻繁,它通常用於對象的值相等性(語義相等)判斷,在 Object 的方法定義中,“==” 比較兩個對象的 object_id 是否一致,通常子類都會重寫覆蓋這個方法,通過比較內部值來判斷對象是否相等。
比如 String 類,他是來計較實際的文字串是否相同,而不在意是否來自同一個內存區域
a = 'abc' #=> 44547600 b = 'abc' + '' #=> 44547540 a == b #=> true
“===” 主要用於 case 語句的相容判斷
通常情況下這中方式與==是一樣的,但是在某些特定情況下,===有特殊的含義:
- 在Range中===用於判斷等號右邊的對象是否包含於等號左邊的Range;
- 正則表達式中用於判斷一個字符串是否匹配模式,
- Class定義===來判斷一個對象是否為類的實例,
- Symbol定義===來判斷等號兩邊的符號對象是否相同
(1..10) === 5 #=> true: 5屬於range 1..10 /\d+/ === '123' #=> true: 字符串匹配這個模式 String === 's' #=> true: "s" 是一個字符串類的實例 :s === 's' #=> false
case some_object when /a regex/ # The regex matches when 2..4 # some_object is in the range 2..4 when lambda {|x| some_crazy_custom_predicate } # the lambda returned true end #等同於 if /a regex/ === some_object # The regex matches elsif (2..4) === some_object # some_object is in the range 2..4 elsif lambda {|x| some_crazy_custom_predicate } === some_object # the lambda returned true end
“eql?” 對象 hash 值判斷
eql? 用於對象 hash 值判斷,如果兩個對象的 hash 值相等,就返回 true,否則返回 false。Object 的定義里,“eql?” 和 “==” 是等價的。通常可以把 “eql?” 看作比 “==” 更嚴格的相等,比如:
1 == 1.0 #=> true 1.eql? 1.0 #=> false
str1 = 'a'
str2 = 'a'
puts str1 == str2 #=> true
str1.hash #=> 104582539
str2.hash #=> 104582539
puts str1.eql? str2 #=> hash值相等 true
str1.object_id #=> 20804940
str2.object_id #=> 20804920
puts str1.equal? str2 #=> object_id不相等 false
“equal?” 相同對象判斷
“equal?” 其實是最簡單的,但是也是最容易讓人搞混的判斷。說它簡單是因為這個方法的語義是比較兩個對象是否相同(是否有相同的 object_id),Object 的方法適用所有對象,不應該對其重寫覆蓋。說它容易讓人搞混,是因為 ruby 和 java 中 “==” 和 “equal?” 方法的語義正好是相反的,ruby 中 “equal?” 表示對象引用相同,而 java 表示對象值相同。
