我想了解这四种方法之间的区别。 我知道默认==调用方法相等? 当两个操作数引用完全相同的对象时,它将返回true。
===默认情况下也调用==哪个调用相等?...好吧,所以如果所有这三个方法都不覆盖,那么我猜
===,==和平等? 做同样的事情?
现在来eql? 这是做什么(默认)? 它是否调用操作数的哈希/ ID?
为什么Ruby有这么多的平等标志? 他们是否应该在语义上有所不同?
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
我将在这里大量引用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)。
这是有效的指针比较。