为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

绝地无双 2019-07-27 14:52:26
equ?,eql?,===和==之间有什么区别?我试图理解这四种方法之间的区别。我知道默认情况下==调用的方法equal?在两个操作数引用完全相同的对象时返回true。===默认情况下也会调用==哪个调用equal?...好吧,如果所有这三个方法都没有被覆盖,那么我想===,==并equal?做同样的事情?现在来了eql?。这是做什么的(默认情况下)?它是否调用操作数的hash / id?为什么Ruby有这么多的平等标志?他们应该在语义上有所不同吗?
查看完整描述

3 回答

?
慕的地8271018

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级别,==仅当objother是同一对象时才返回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

请参阅我的答案,以获得一个简洁的例子,说明caseRegex如何使代码更清晰。当然,通过提供自己的===实现,您可以获得自定义case语义。

eql?Hash平等

eql?如果obj并且other引用相同的散列键,则该方法返回true 。这用于Hash测试成员是否相等。对于类的对象Objecteql?是同义词==子类通常通过eql?对其重写==方法进行别名来继续这种传统,但也有例外。Numeric例如,类型执行跨越==但不跨越的类型转换eql?,因此:

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

因此,您可以自由地覆盖它以供自己使用,或者您可以覆盖==和使用,alias :eql? :==因此这两种方法的行为方式相同。

equal? - 身份比较

与此不同==,该equal?方法永远不应被子类覆盖:它用于确定对象标识(即a.equal?(b)iff a与其相同的对象b)。

这实际上是指针比较。


查看完整回答
反对 回复 2019-07-27
  • 3 回答
  • 0 关注
  • 987 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信