猿问

equ?,eql?,===和==之间有什么区别?

equ?,eql?,===和==之间有什么区别?

我试图理解这四种方法之间的区别。我知道默认情况下==调用的方法equal?在两个操作数引用完全相同的对象时返回true。

===默认情况下也会调用==哪个调用equal?...好吧,如果所有这三个方法都没有被覆盖,那么我想=====equal?做同样的事情?

现在来了eql?。这是做什么的(默认情况下)?它是否调用操作数的hash / id?

为什么Ruby有这么多的平等标志?他们应该在语义上有所不同吗?


绝地无双
浏览 1002回答 3
3回答

慕的地8271018

我将在这里大量引用Object文档,因为我认为它有一些很好的解释。我鼓励你阅读它,以及这些方法的文档,因为它们在其他类中被覆盖,比如String。旁注:如果您想在不同的对象上尝试这些,请使用以下内容:class Object   def all_equals(o)     ops = [:==, :===, :eql?, :equal?]     Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]   endend"a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}== - 通用“平等”在Object级别,==仅当obj且other是同一对象时才返回true 。通常,在子类中重写此方法以提供特定于类的含义。这是最常见的比较,因此是您(作为一个类的作者)决定两个对象是否“相等”的最基本的地方。=== - 案件平等对于类Object,实际上与调用相同#==,但通常由后代重写,以在case语句中提供有意义的语义。这非常有用。有趣===实现的事情的例子:范围正则表达式Proc(在Ruby 1.9中)所以你可以这样做:case some_objectwhen /a regex/   # The regex matcheswhen 2..4   # some_object is in the range 2..4when lambda {|x| some_crazy_custom_predicate }   # the lambda returned trueend请参阅我的答案,以获得一个简洁的例子,说明case+ Regex如何使代码更清晰。当然,通过提供自己的===实现,您可以获得自定义case语义。eql?- Hash平等eql?如果obj并且other引用相同的散列键,则该方法返回true 。这用于Hash测试成员是否相等。对于类的对象Object,eql?是同义词==。子类通常通过eql?对其重写==方法进行别名来继续这种传统,但也有例外。Numeric例如,类型执行跨越==但不跨越的类型转换eql?,因此:1 == 1.0     #=> true1.eql? 1.0   #=> false因此,您可以自由地覆盖它以供自己使用,或者您可以覆盖==和使用,alias :eql? :==因此这两种方法的行为方式相同。equal? - 身份比较与此不同==,该equal?方法永远不应被子类覆盖:它用于确定对象标识(即a.equal?(b)iff a与其相同的对象b)。这实际上是指针比较。
随时随地看视频慕课网APP

相关分类

Ruby
我要回答