Ruby里4种比较函数(equal?, eql?, ==, ===)详解
Ruby里面有4种比较方法,equal?,eql?,==,===,而且在不同的类里面表现的很不一样。在使用的时候也特别容易搞糊涂。这篇博文将演示一些代码来讲解各个方法。
==-类意义上的相等,需要每个类自己定义实现
在特定类中觉得两个对象是否相同,需要看业务上的逻辑表象,所有由程序员覆盖该方法的定义,决定两个对象是否相同。
比如String类,他是来计较实际的文字串是否相同,而不在意是否来自同一个内存区域。
>>a="abc" #=>"abc" >>b=a+"" #=>"abc" ?>a==b #=>true >>a.object_id #=>70255156346640 >>b.object_id #=>70255156340640
===-用在case语句里时会调用的方法
通常用在case比较调用该方法,比如
casesome_object when/aregex/ #Theregexmatches whenString #some_objectiskindofString when2..4 #some_objectisintherange2..4 whenlambda{|x|some_crazy_custom_predicate} #thelambdareturnedtrue end
等同于
if/aregex/===some_object #Theregexmatches elsifString===some_object #some_objectiskindofobject elsif(2..4)===some_object #some_objectisintherange2..4 elsiflambda{|x|some_crazy_custom_predicate}===some_object #thelambdareturnedtrue end
eql?-通常意义上的相等
如果两个对象的值相同将返回true,如果重新定义了子类的==方法,一般需要alias到eql?方法。当然也有例外,整数与小数的比较两个方法的返回值就不同。
1==1.0#=>true 1.eql?1.0#=>false
eql?用在Hash里面用来做成员值比较
[1]pry(main)>hash=Hash.new #=>{} [2]pry(main)>hash[2]="a" #=>"a" [3]pry(main)>hash[2.0]="b" #=>"b" [4]pry(main)>hash[2] #=>"a" [5]pry(main)>hash[2.0] #=>"b" [6]pry(main)>hash[2.00]="c" #=>"c" [7]pry(main)>hash[2.0] #=>"c"
所以什么时候应该覆盖这个方法就看你想让他在Hash比较时如何表现。
equal?-内存地址相同的对象
该方法不应该被子类覆盖
比较的是两个对象在内存中是否相同,是否有同一个object_id值
Rails中及时相同的对象
q=User.first UserLoad(40.4ms)SELECT"users".*FROM"users"ORDERBY"users"."id"ASCLIMIT1 #=>#<Userid:1,email:"ryan@wongyouth.com"> q2=User.first UserLoad(0.4ms)SELECT"users".*FROM"users"ORDERBY"users"."id"ASCLIMIT1 #=>#<Userid:1,email:"ryan@wongyouth.com"> q.equal?q2 #=>false
记忆方法
- ==按业务需求覆盖该方法
- ===覆盖case语句时的表现
- eql?别名到==方法,需要时覆盖方法改变Hash比较时的表现
- equal?不改动