3 回答
TA贡献1796条经验 获得超4个赞
我将在这里大量引用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)
iffa
与其相同的对象b
)。
这实际上是指针比较。
- 3 回答
- 0 关注
- 987 浏览
添加回答
举报