Was sind Ruby-Variablen, denen bei Zeichen ( @@
) ein Double vorangestellt ist ? Mein Verständnis einer Variablen, der ein at-Zeichen vorangestellt ist, ist, dass es sich um eine Instanzvariable handelt, wie in PHP:
PHP-Version
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Rubinäquivalent
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
Was bedeutet das doppelte at-Zeichen @@
und wie unterscheidet es sich von einem einzelnen at-Zeichen?
@
innerhalb vonself
Methoden) verwenden, keine Klassenvariablen (@@
). Siehe die Litanei der Gründe dafür in den Antworten unten.Antworten:
Eine Variable mit dem Präfix
@
ist eine Instanzvariable , während eine mit dem Präfix@@
eine Klassenvariable ist . Schauen Sie sich das folgende Beispiel an. Die Ausgabe erfolgt in den Kommentaren am Ende derputs
Zeilen:Sie können sehen, dass dies
@@shared
zwischen den Klassen geteilt wird. Durch Festlegen des Werts in einer Instanz von eins wird der Wert für alle anderen Instanzen dieser Klasse und sogar für untergeordnete Klassen, bei denen eine Variable benannt ist@shared
, mit eins geändert@
nicht wäre.[Aktualisieren]
Wie Phrogz in den Kommentaren erwähnt, ist es in Ruby üblich, Daten auf Klassenebene mit einer Instanzvariablen für die Klasse selbst zu verfolgen . Dies kann ein schwieriges Thema sein, um sich Gedanken zu machen, und es gibt viele zusätzliche Informationen zu diesem Thema, aber denken Sie daran, dass es die
Class
Klasse ändert , aber nur die Instanz derClass
Klasse, mit der Sie arbeiten. Ein Beispiel:Ich habe das
Square
Beispiel (welche Ausgabennil
) beigefügt , um zu demonstrieren, dass sich dies möglicherweise nicht zu 100% wie erwartet verhält. das Artikel, den ich oben verlinkt habe, enthält viele zusätzliche Informationen zu diesem Thema.Denken Sie auch daran, dass Sie, wie bei den meisten Daten, mit Klassenvariablen in einer Multithread-Umgebung äußerst vorsichtig sein sollten , wie im Kommentar von dmarkow angegeben.
quelle
ruby class << self end
Block tut, insbesondere den Operator <<.class << self
sehen Sie dies@
- Instanzvariable einer Klasse@@
- Klassenvariable, in einigen Fällen auch als statische Variable bezeichnetEine Klassenvariable ist eine Variable, die von allen Instanzen einer Klasse gemeinsam genutzt wird. Dies bedeutet, dass für alle aus dieser Klasse instanziierten Objekte nur ein Variablenwert vorhanden ist. Wenn eine Objektinstanz den Wert der Variablen ändert, ändert sich dieser neue Wert im Wesentlichen für alle anderen Objektinstanzen.
Eine andere Art, an Klassenvariablen zu denken, ist als globale Variablen im Kontext einer einzelnen Klasse. Klassenvariablen werden deklariert, indem dem Variablennamen zwei
@
Zeichen (@@
) vorangestellt werden . Klassenvariablen müssen zum Zeitpunkt der Erstellung initialisiert werdenquelle
@@
bezeichnet eine Klassenvariable, dh sie kann vererbt werden.Dies bedeutet, dass beim Erstellen einer Unterklasse dieser Klasse die Variable geerbt wird. Wenn Sie also eine Klasse
Vehicle
mit der Klassenvariablen haben,@@number_of_wheels
wenn Sie eine erstellen,class Car < Vehicle
hat auch diese die Klassenvariable@@number_of_wheels
quelle
Vehicle
mit der Klassenvariablen haben@@number_of_wheels
,class Car < Vehicle
dann hat sie auch die Klassenvariable@@number_of_wheels
class Vehicle
with habe@number_of_wheels
,class Car < Vehicle
wird auch eine Instanzvariable aufgerufen@number_of_wheels
. Der Hauptunterschied zu Klassenvariablen besteht darin, dass die Klassen dieselbe Variable haben, z. B. wenn Sie eine ändern, werden die anderen geändert.@ und @@ in Modulen funktionieren auch anders, wenn eine Klasse dieses Modul erweitert oder enthält.
So gegeben
Dann erhalten Sie die unten aufgeführten Ausgaben als Kommentare
Verwenden Sie also @@ in Modulen für Variablen, die für alle Verwendungszwecke verwendet werden sollen, und @ in Modulen für Variablen, die für jeden Verwendungskontext separat verwendet werden sollen.
quelle
Die Antworten sind teilweise korrekt, da @@ tatsächlich eine Klassenvariable ist, die pro Klassenhierarchie angegeben ist, was bedeutet, dass sie von einer Klasse, ihren Instanzen und ihren untergeordneten Klassen und ihren Instanzen gemeinsam genutzt wird.
Dies wird ausgegeben
Es gibt also nur eine @@ -Variable für Personen-, Studenten- und Abschlussklassen, und alle Klassen- und Instanzmethoden dieser Klassen beziehen sich auf dieselbe Variable.
Es gibt eine andere Möglichkeit, eine Klassenvariable zu definieren, die für ein Klassenobjekt definiert ist (Denken Sie daran, dass jede Klasse tatsächlich eine Instanz von etwas ist, das tatsächlich die Klassenklasse ist, aber es ist eine andere Geschichte). Sie verwenden die @ -Notation anstelle von @@, können jedoch nicht über Instanzmethoden auf diese Variablen zugreifen. Sie benötigen Klassenmethoden-Wrapper.
Hier ist @people pro Klasse anstelle der Klassenhierarchie einzeln, da es sich tatsächlich um eine Variable handelt, die in jeder Klasseninstanz gespeichert ist. Dies ist die Ausgabe:
Ein wichtiger Unterschied besteht darin, dass Sie nicht direkt über Instanzmethoden auf diese Klassenvariablen (oder Klasseninstanzvariablen, die Sie sagen können) zugreifen können, da @people in einer Instanzmethode auf eine Instanzvariable dieser bestimmten Instanz der Klassen Person, Student oder Graduate verweisen würde .
Während andere Antworten korrekt angeben, dass @myvariable (mit einfacher @ -Notation) immer eine Instanzvariable ist, bedeutet dies nicht unbedingt, dass es sich nicht um eine einzelne gemeinsam genutzte Variable für alle Instanzen dieser Klasse handelt.
quelle