Ruby is_a? vs ===

问题描述:

is_a?===的区别是什么?Ruby is_a? vs ===

运行此代码:

puts myObj.class 
puts myObj.is_a?(Hash) 
puts myObj === Hash #Curious 
puts Hash === myObj 

的Outputis:

Hash 
true 
false  #Why? 
true 
+0

许多风格指南建议不要使用=>真

更多信息== =在您的代码中,因为它将用于内置的case构造。 –

他们大多在本质上是相同的,但===也可以在子类中重写。

===通常是一个轻量级的包装物,主要是为了让案例构造可以隐式使用它。默认情况下,它是一个wrapper aroundObject#is_a?(请参阅源文件)。

然而,这两个是打算是等效的构造。

+3

[默认实现](http://ruby-doc.org/core-2.1.1/Module。html#method-i-3D-3D-3D)'mod === obj'实际上调用'obj.is_a?(mod)' – Stefan

+0

@Stefan是的,这就是为什么我称它为包装。也许我应该澄清它是'is_a?'的包装。谢谢 – Agis

清除例如

1)$> Integer === 1 # => true 

2)$> 1 === Integer # => false 

1)1 整数的一个实例,但2)整数不是1

实例但如果是任何一个实例也返回true它的子类,例如:

$ > Numeric === 1 # => true 
$ > Numeric === 1.5 # => true 

$ > Fixnum === 1 # => true 
$ > Fixnum === 1.5 # => false 

许多Ruby的内置类,如String的,Range和Regexp提供它们自己的===运算符实现,也称为case-equality,triple equals或threequals。因为它在每个类中的实现方式不同,所以它的行为将有所不同,具体取决于所调用对象的类型。通常,如果右侧的对象“属于”或“是左侧的对象的成员”,则返回true。例如,它可以用来测试一个对象是否是一个类的实例(或它的一个子类)。

String === "zen" # Output: => true 
Range === (1..2) # Output: => true 
Array === [1,2,3] # Output: => true 
Integer === 2 # Output: => true 

使用可能最适合该工作的其他方法可以获得相同的结果。通常尽可能明确地编写易于阅读的代码,而不会牺牲效率和简洁性。

2.is_a? Integer # Output: => true 
2.kind_of? Integer # Output: => true 
2.instance_of? Integer # Output: => false 

注意最后一个例子返回false,因为整数例如2是Fixnum类的实例,它是Integer类的一个子类。 ===,is_a?和instance_of?如果对象是给定类或任何子类的实例,则方法返回true。 instance_of方法更严格,只有当对象是该类的实例时才返回true,而不是子类。

is_a?和kind_of?方法在内核模块中实现,该模块由Object类混合。两者都是相同方法的别名。我们来验证:

Kernel.instance_method(?:kind_of)== Kernel.instance_method(?:is_a)#输出:在this blog post about ruby operators.