571 Stimmen

Ruby: kind_of? vs. instance_of? vs. is_a?

Worin besteht der Unterschied? Wann sollte ich welche verwenden? Warum gibt es so viele von ihnen?

727voto

sepp2k Punkte 352762

kind_of? y is_a? sind synonym.

instance_of? unterscheidet sich von den beiden anderen dadurch, dass es nur true wenn das Objekt eine Instanz genau dieser Klasse und keine Unterklasse ist.

Exemple :

  • "hello".is_a? Object y "hello".kind_of? Object return true denn "hello" es un String y String ist eine Unterklasse von Object .
  • Allerdings "hello".instance_of? Object gibt zurück. false .

25voto

Jörg W Mittag Punkte 349574

Worin besteht der Unterschied?

Aus der Dokumentation:

- ( Boolesche ) instance_of?(class)

Rückgabe true si obj ist eine Instanz der angegebenen Klasse.

und:

- ( Boolesche ) is_a?(class)
- ( Boolesche ) kind_of?(class)

Rückgabe true si class ist die Klasse der obj , oder wenn class ist eine der Oberklassen von obj oder Module, die in obj .

Wenn das unklar ist, wäre es gut zu wissen, was genau unklar ist, so dass die Dokumentation verbessert werden kann.

Wann sollte ich was verwenden?

Niemals. Verwenden Sie stattdessen Polymorphismus.

Warum gibt es so viele von ihnen?

Ich würde es nicht als zwei "viele". Es gibt zwei von ihnen, weil sie zwei verschiedene Dinge tun.

9voto

kuonirat Punkte 313

Es ist eher Ruby-like, Objekte zu fragen, ob sie auf eine benötigte Methode reagieren oder nicht, indem man respond_to? . Dies ermöglicht sowohl eine minimale Schnittstelle als auch eine implementierungsunabhängige Programmierung.

Es ist natürlich nicht immer anwendbar, daher gibt es immer noch die Möglichkeit, nach einem konservativeren Verständnis von "Typ" zu fragen, der eine Klasse oder eine Basisklasse ist, die die Methoden verwendet, nach denen Sie fragen.

5voto

Boris Stitnicky Punkte 12077

Ich würde auch nicht sagen, dass zwei viele ( is_a? y kind_of? sind Aliase der gleichen Methode), aber wenn Sie mehr Möglichkeiten sehen wollen, wenden Sie sich an #class Methode:

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

0voto

Adam Scott Punkte 1

https://stackoverflow.com/a/3893305/10392483 ist eine großartige Erklärung ... um dem Ganzen etwas mehr Farbe zu verleihen, verwende ich is_a? für "Primäre" (String, Array, vielleicht Hash, usw.)

Alors "hello".is_a?(String) , [].is_a?(Array) , {}.is_a?(Hash)

Für alles andere verwende ich in der Regel instance_of? (Animal.new.instance_of?(Animal)

Ich sage "tendenziell", weil die Sache nicht ganz so eindeutig ist. Nehmen Sie zum Beispiel:

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

Wie Sie sehen, ist x sowohl ein Hund als auch ein Tier, aber es ist nur eine Instanz von Hund.

Für mich ist das eine Frage der Spezifität:

  • Wenn ich nur wissen will, dass es sich um eine Animal und nicht ein Plant Ich benutze is_a?
  • Wenn es mich interessiert, dass es ein Dog und nicht ein Cat Ich benutze instance_of?

Sie können dies dann weiterführen. Wenn es mir wichtig ist, dass es ein Sighthound und nicht ein Bloodhound vorausgesetzt, beide sind Unterklassen von Dog . Dann möchte ich es vielleicht noch spezifischer machen.

Davon abgesehen, is_a?(Animal|Dog|Sighthound) wird immer funktionieren. Aber wenn Sie sich für die spezifische Unterklasse interessieren, instance_of? ist immer spezifischer.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X