equal, eql, ===, and ==,有什么区别?

  • 回答 (2)
  • 关注 (0)
  • 查看 (61)

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

===默认情况下也调用==哪个调用相等?...好吧,所以如果所有这三个方法都不覆盖,那么我猜

===,==和平等? 做同样的事情?

现在来eql? 这是做什么(默认)? 它是否调用操作数的哈希/ ID?

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

nr348399nr348399提问于
御姐万岁回答于

uby公开了几种处理相等的方法:

a.equal?(b)#对象标识 - a和b是指同一个对象

a.eql?(b)#对象等价 - a和b具有相同的值

a == b#对象等价 - a和b与类型转换具有相同的值。

点击下面的链接继续阅读,这给了我一个明确的总结了解。

https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/equality-matchers

akjok54stay hungry stay foolish回答于

我将在这里大量引用Object文档,因为我认为它有一些很好的解释。我鼓励你阅读它,以及这些方法的文档,因为它们在其他类中被重写,比如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_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}

== - 通用的“平等”

在对象级别,==只有当obj和other是同一个对象时才返回true 。通常,这个方法在子类中被覆盖,以提供类特定的含义。

这是最常见的比较,因此是你(作为一个类的作者)决定两个对象是否“相等”的最基本的地方。

=== - 案件平等

对于类Object来说,实际上与调用相同#==,但通常被后代覆盖,以在case语句中提供有意义的语义。

这非常有用。有趣的===实现的东西的例子:

范围

正则表达式

Proc(在Ruby 1.9中)

所以你可以做这样的事情:

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

在这里看到我的答案是一个很好的例子,说明case+ Regex如何使代码变得更加清晰。当然,通过提供你自己的===实现,你可以得到自定义的case语义。

eql?- Hash平等

eql?如果obj和other引用相同的散列键,该方法返回true 。这被用来Hash测试成员的平等。对于课堂上的对象Object,eql?是同义词==。通常,子类别通过eql?重写它们的重写==方法来延续这个传统,但也有例外。Numeric类型,例如,执行类型转换==,但不跨越eql?,所以:

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

所以你可以自由的覆盖这个用于你自己的用途,或者你可以覆盖==和使用alias :eql? :==这两个方法的行为是一样的。

equal? - 身份比较

与此不同的是==,这个equal?方法不应该被子类所覆盖:它被用来确定对象的标识(也就是说,a.equal?(b)iff a与对象相同b)。

这是有效的指针比较。

扫码关注云+社区

领取腾讯云代金券