有什么不同?什么时候用哪个?为什么会有这么多?
当前回答
https://stackoverflow.com/a/3893305/10392483是一个很好的解释…为了增加一些颜色,我倾向于使用is_a?对于“原语”(字符串,数组,可能是哈希等)
所以“hello”.is_a ?(字符串),[].is_a ?(数组),{}.is_a ?(哈希)
对于其他情况,我倾向于使用instance_of?(Animal.new.instance_of ?(动物)
我说倾向,是因为它不是那么明确。举个例子:
class Animal;end
class Dog < Animal;end
x = Dog.new
x.is_a?(Dog) # => true
x.is_a?(Animal) # => true
x.instance_of?(Dog) # => true
x.instance_of?(Animal) # => false
如你所见,x既是Dog也是Animal,但它只是Dog的一个实例。
我认为这是一个具体的问题:
如果我只想知道它是动物而不是植物,我将使用is_a? 如果我关心它是狗而不是猫,我将使用instance_of?
然后你可以更进一步。如果我关心它是视觉猎犬而不是寻血猎犬,假设两者都是狗的子类。那我可能想说得更具体些。
也就是说,is_a?(Animal|Dog|Sighthound)总是有用的。但如果您关心特定的子类instance_of?总是更具体。
其他回答
kind_of吗?和is_a吗?是同义的。
instance_of吗?与其他两个不同的是,它只在对象是该类的实例而不是子类时才返回true。
例子:
“你好”.is_a吗?对象和"hello".kind_of?对象返回true,因为"hello"是一个String,而String是Object的子类。 然而“hello”.instance_of吗?对象返回false。
有什么不同?
从文档中可以看到:
- (Boolean) instance_of?(class)如果obj是给定类的实例,则返回true。
and:
- (Boolean) is_a?(class)- (Boolean) kind_of?(class)如果class是obj的类,或者如果class是obj的超类之一或obj中包含的模块,则返回true。
如果这一点不清楚,那么最好能知道到底是什么地方不清楚,这样就可以改进文档。
什么时候用哪个?
从来没有。请使用多态性。
为什么会有这么多?
我不认为两个是“很多”。它们有两个,因为它们做两种不同的事情。
https://stackoverflow.com/a/3893305/10392483是一个很好的解释…为了增加一些颜色,我倾向于使用is_a?对于“原语”(字符串,数组,可能是哈希等)
所以“hello”.is_a ?(字符串),[].is_a ?(数组),{}.is_a ?(哈希)
对于其他情况,我倾向于使用instance_of?(Animal.new.instance_of ?(动物)
我说倾向,是因为它不是那么明确。举个例子:
class Animal;end
class Dog < Animal;end
x = Dog.new
x.is_a?(Dog) # => true
x.is_a?(Animal) # => true
x.instance_of?(Dog) # => true
x.instance_of?(Animal) # => false
如你所见,x既是Dog也是Animal,但它只是Dog的一个实例。
我认为这是一个具体的问题:
如果我只想知道它是动物而不是植物,我将使用is_a? 如果我关心它是狗而不是猫,我将使用instance_of?
然后你可以更进一步。如果我关心它是视觉猎犬而不是寻血猎犬,假设两者都是狗的子类。那我可能想说得更具体些。
也就是说,is_a?(Animal|Dog|Sighthound)总是有用的。但如果您关心特定的子类instance_of?总是更具体。
使用respond_to?来询问对象是否响应您需要的方法更像ruby。这允许最小化接口和不考虑实现的编程。
当然,它并不总是适用的,因此仍然有可能使用您所询问的方法来询问对“类型”(即类或基类)的更保守的理解。
我也不会调用two many (is_a?和kind_of吗?是同一个方法的别名),但如果你想看到更多的可能性,请将注意力转向#class method:
A = Class.new
B = Class.new A
a, b = A.new, B.new
b.class < A # true - means that b.class is a subclass of A
a.class < B # false - means that a.class is not a subclass of A
# Another possibility: Use #ancestors
b.class.ancestors.include? A # true - means that b.class has A among its ancestors
a.class.ancestors.include? B # false - means that B is not an ancestor of a.class