Ruby: kind_of ?与instance_of吗?与is_a吗?

有什么不同?什么时候用哪个?为什么会有这么多?

227525 次浏览

kind_of?is_a?是同义词。

instance_of?与其他两个不同之处在于,如果对象是该类的实例,而不是子类,它只返回true

例子:

  • "hello".is_a? Object"hello".kind_of? Object返回true,因为"hello"StringStringObject的子类。
  • 但是"hello".instance_of? Object返回false

有什么不同?

从文档中可以看到:

# EYZ3 # EYZ4

和:

# EYZ8 # EYZ9

如果不清楚,最好能知道完全是什么不清楚,这样文档就可以改进了。

什么时候用哪个?

从来没有。请使用多态性。

为什么会有这么多?

我不会称两个为“很多”。它们有两个,因为它们做两种不同的事情。

使用respond_to?询问对象是否响应您需要的方法更像ruby。这允许最小化接口和不考虑实现的编程。

当然,它并不总是适用的,因此仍然有可能使用您所询问的方法来询问对“类型”(即类或基类)的更保守的理解。

我也不会调用两个(is_a?kind_of?是同一个方法的别名),但如果你想看到更多的可能性,把你的注意力转向#class方法:

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

https://stackoverflow.com/a/3893305/10392483是个很好的解释……为了增加一些色彩,我倾向于使用is_a?来表示“primatives"(字符串,数组,哈希等)

那么"hello".is_a?(String)[].is_a?(Array){}.is_a?(Hash)

对于其他任何东西,我倾向于使用instance_of? (Animal.new.instance_of?(Animal)

我说倾向,是因为它不是那么明确。举个例子:

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的一个实例。

我认为这是一个具体的问题:

  • 如果我只想知道它是Animal而不是Plant,我将使用is_a?
  • 如果我关心它是Dog而不是Cat,我将使用instance_of?

然后你可以更进一步。如果我关心它是Sighthound而不是Bloodhound,假设两者都是Dog的子类。那我可能想说得更具体些。

也就是说,is_a?(Animal|Dog|Sighthound)总是可以工作的。但是如果您关心特定的子类,instance_of?总是更具体。