Ruby is_a?vs ===

Ale*_*lex 4 ruby ruby-on-rails operators

什么是is_a?===?之间的区别?

运行此代码:

puts myObj.class
puts myObj.is_a?(Hash)
puts myObj === Hash   #Curious 
puts Hash  === myObj
Run Code Online (Sandbox Code Playgroud)

输出:

Hash
true
false        #Why?
true
Run Code Online (Sandbox Code Playgroud)

Bru*_*cca 6

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
Run Code Online (Sandbox Code Playgroud)

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

2.is_a? Integer   # Output: => true
2.kind_of? Integer  # Output: => true
2.instance_of? Integer # Output: => false
Run Code Online (Sandbox Code Playgroud)

请注意,最后一个示例返回false,因为整数(如2)是Fixnum类的实例,它是类的子Integer类.的===,is_a?kind_of?如果对象是给定类或子类的实例方法返回true.该instance_of?方法更严格,只有当对象是该确切类的实例而不是子类时才返回true.

is_a?kind_of?方法在本实施中Kernel模块,其由混合Object类.两者都是同一方法的别名.我们来验证:

Kernel.instance_method(:kind_of?) == Kernel.instance_method(:is_a?)
# Output: => true
Run Code Online (Sandbox Code Playgroud)

有关ruby运算符的更多信息,请参阅此博客文章.


Agi*_*gis 3

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

===通常是一个轻量级的包装器,主要是为了让 case 结构可以隐式地使用它。默认情况下它是一个包装器 Object#is_a?(参见源代码)。

然而,这两个旨在是等效的构造。

  • [默认实现](http://ruby-doc.org/core-2.1.1/Module.html#method-i-3D-3D-3D) `mod === obj` 实际上调用 `obj.is_a? (模组)` (4认同)