equal,eql ?, ===和==之间有什么区别? [英] What's the difference between equal?, eql?, ===, and ==?

查看:162
本文介绍了equal,eql ?, ===和==之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解这四种方法的区别。我默认知道 == 调用方法 equal?,当两个操作数指向完全相同的对象时返回true 。



=== 默认情况下还调用 == 等于? ...好吧,所以如果所有这三个方法都没有重写,那么我猜测
=== == 等于?做同样的事吗?



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



为什么Ruby有这么多的等号?

解决方案

我要大量引用对象文档,因为我认为它有一些很好的解释。我鼓励您阅读它,以及这些方法的文档,因为它们在其他类中被覆盖,例如 String



注意:如果您想在不同物件上试用这些功能,请使用以下方式:

  class Object 
def all_equals(o)
ops = [:==,:===,:eql ?,:equal?]
Hash [ops.map(&:to_s).zip(ops.map {| s | send(s,o)})]
end
end

a.all_equalsa#=> {===> true,====> true,eql?=> true,equal?=> false}
/ pre>




== - genericequality h2>


在对象级别, == 仅当 obj 其他是同一个对象。通常,此方法在后代类中被覆盖以提供类特定的含义。


这是最常见的比较,



===

/ code> - case equality




对于Object类,与调用#== ,但是通常由后代重载以在语句中提供有意义的语义。


这是非常有用的。具有有趣的 === 实施的事情示例:




  • 范围

  • Regex

  • Proc(在Ruby 1.9中)



你可以这样做:

  case some_object 
when / a regex /
#regex matches
当2..4
#some_object在范围2..4
当lambda {| x | some_crazy_custom_predicate}
#lambda返回true
end

请参阅我在这里回答一个整洁的例子如何 case + Regex 可以使代码更清晰。当然,通过提供自己的 === 实现,你可以得到自定义的 case 语义。



eql? - Hash 相等




eql?方法返回true if obj code>其他指的是相同的散列键。这由 Hash 使用来测试成员是否相等。 对于 Object eql?的对象与 code>。子类通常通过将 eql?别名替换为其重写 == 方法,但也有例外。 数字类型,例如,对 == 执行类型转换,但不能跨 eql? ,所以:

  1 == 1.0#=> true 
1.eql? 1.0#=> false


因此您可以根据自己的需要,或者您可以覆盖 == 并使用别名:eql?



等于? -

身份比较




== 不同, 方法不应该被子类覆盖:它用于确定对象身份(即 a.equal?(b) iff a 是与 b 相同的对象。


这是有效的指针比较。


I am trying to understand the difference between these four methods. I know by default that == calls the method equal? which returns true when both operands refer to exactly the same object.

=== by default also calls == which calls equal?... okay, so if all these three methods are not overridden, then I guess ===, == and equal? do exactly the same thing?

Now comes eql?. What does this do (by default)? Does it make a call to the operand's hash/id?

Why does Ruby have so many equality signs? Are they supposed to differ in semantics?

解决方案

I'm going to heavily quote the Object documentation here, because I think it has some great explanations. I encourage you to read it, and also the documentation for these methods as they're overridden in other classes, like String.

Side note: if you want to try these out for yourself on different objects, use something like this:

class Object
  def all_equals(o)
    ops = [:==, :===, :eql?, :equal?]
    Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
  end
end

"a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}


== — generic "equality"

At the Object level, == returns true only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.

This is the most common comparison, and thus the most fundamental place where you (as the author of a class) get to decide if two objects are "equal" or not.

=== — case equality

For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

This is incredibly useful. Examples of things which have interesting === implementations:

  • Range
  • Regex
  • Proc (in Ruby 1.9)

So you can do things like:

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

See my answer here for a neat example of how case+Regex can make code a lot cleaner. And of course, by providing your own === implementation, you can get custom case semantics.

eql?Hash equality

The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition by aliasing eql? to their overridden == method, but there are exceptions. Numeric types, for example, perform type conversion across ==, but not across eql?, so:

1 == 1.0     #=> true
1.eql? 1.0   #=> false

So you're free to override this for your own uses, or you can override == and use alias :eql? :== so the two methods behave the same way.

equal? — identity comparison

Unlike ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b).

This is effectively pointer comparison.

这篇关于equal,eql ?, ===和==之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆