Worin besteht der Unterschied? Wann sollte ich welche verwenden? Warum gibt es so viele von ihnen?
Antworten
Zu viele Anzeigen?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
returntrue
denn"hello"
es unString
yString
ist eine Unterklasse vonObject
.- Allerdings
"hello".instance_of? Object
gibt zurück.false
.
Worin besteht der Unterschied?
Aus der Dokumentation:
- ( Boolesche )
instance_of?(class)
Rückgabe
true
siobj
ist eine Instanz der angegebenen Klasse.
und:
- ( Boolesche )
is_a?(class)
- ( Boolesche )kind_of?(class)
Rückgabe
true
siclass
ist die Klasse derobj
, oder wennclass
ist eine der Oberklassen vonobj
oder Module, die inobj
.
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.
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.
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
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 einPlant
Ich benutzeis_a?
- Wenn es mich interessiert, dass es ein
Dog
und nicht einCat
Ich benutzeinstance_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.