is_a?
和===
之间有什么区别?
运行此代码:
puts myObj.class
puts myObj.is_a?(Hash)
puts myObj === Hash #Curious
puts Hash === myObj
输出:
Hash
true
false #Why?
true
答案 0 :(得分: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
使用可能最适合工作的其他方法可以获得相同的结果。通常,在不牺牲效率和简洁性的情况下,通过尽可能明确地编写易于阅读的代码通常会更好。
2.is_a? Integer # Output: => true
2.kind_of? Integer # Output: => true
2.instance_of? Integer # Output: => false
请注意,最后一个示例返回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
的更多信息
答案 1 :(得分:3)
它们本质上大致相同,但===
也可以在子类中重写。
===
通常是一个简单的包装器,主要是为了使case结构可以隐式使用它。默认情况下,它是wrapper around Object#is_a?
(请参阅来源)。
然而,这两个意图是等效结构。
答案 2 :(得分:1)
清除示例
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