equal,eql ?, ===和==之间有什么区别? [英] What's the difference between equal?, eql?, ===, and ==?
问题描述
我想了解这四种方法的区别。我默认知道 ==
调用方法 equal?
,当两个操作数指向完全相同的对象时返回true 。
===
默认情况下还调用 ==
等于?
...好吧,所以如果所有这三个方法都没有重写,那么我猜测
===
, ==
和等于?
做同样的事吗?
现在 eql?
。这是什么(默认)?它是否调用操作数的hash / id?
为什么Ruby有这么多的等号?
我要大量引用对象文档,因为我认为它有一些很好的解释。我鼓励您阅读它,以及这些方法的文档,因为它们在其他类中被覆盖,例如 String 。
注意:如果您想在不同物件上试用这些功能,请使用以下方式:
class Object
/ pre>
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}
==
- 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 ifobj
code>其他指的是相同的散列键。这由Hash
使用来测试成员是否相等。 对于Object
,eql?
的对象与code>。
子类通常通过将eql?
别名替换为其重写==
方法,但也有例外。数字
类型,例如,对==
执行类型转换,但不能跨eql?
,所以:1 == 1.0#=> true
1.eql? 1.0#=> false
因此您可以根据自己的需要,或者您可以覆盖 ==
并使用别名:eql?
等于?
- 身份比较
与
==
不同,方法不应该被子类覆盖:它用于确定对象身份(即
a.equal?(b)
iffa 是与
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 ifobj
andother
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 ifobj
andother
refer to the same hash key. This is used byHash
to test members for equality. For objects of classObject
,eql?
is synonymous with==
. Subclasses normally continue this tradition by aliasingeql?
to their overridden==
method, but there are exceptions.Numeric
types, for example, perform type conversion across==
, but not acrosseql?
, 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
==
, theequal?
method should never be overridden by subclasses: it is used to determine object identity (that is,a.equal?(b)
iffa
is the same object asb
).
This is effectively pointer comparison.
这篇关于equal,eql ?, ===和==之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!