Co to są zmienne Ruby poprzedzone podwójnym znakiem ( @@
)? Moje rozumienie zmiennej poprzedzonej znakiem at jest takie, że jest to zmienna instancji, tak jak w PHP:
Wersja PHP
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Odpowiednik Ruby
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
Co oznacza podwójny znak @@
i czym różni się od pojedynczego znaku?
@
wewnątrzself
metod), a nie zmiennych klas (@@
). Zobacz litanię powodów w poniższych odpowiedziach.Odpowiedzi:
Zmienna z prefiksem
@
jest zmienną instancji , a zmienna z prefiksem@@
jest zmienną klasową . Sprawdź następujący przykład; jego wynik jest w komentarzach na końcuputs
linii:Możesz zobaczyć, że
@@shared
jest to współdzielone między klasami; ustawienie wartości w jednej instancji zmienia wartość dla wszystkich innych instancji tej klasy, a nawet klas podrzędnych, w przypadku których zmienna o nazwie@shared
z jedynką@
nie byłaby.[Aktualizacja]
Jak wspomina Phrogz w komentarzach, w Rubim powszechnym idiomem jest śledzenie danych na poziomie klasy za pomocą zmiennej instancji w samej klasie . Może to być trudny temat do ogarnięcia umysłem i jest wiele dodatkowych lektur na ten temat, ale pomyśl o tym jako o modyfikacji
Class
klasy, ale tylko o wystąpieniuClass
klasy, z którą pracujesz. Przykład:Podałem
Square
przykład (które wynikinil
), aby zademonstrować, że może to nie zachowywać się w 100% zgodnie z oczekiwaniami; artykuł I połączone powyżej ma wiele dodatkowych informacji na ten temat.Należy również pamiętać, że podobnie jak w przypadku większości danych, należy zachować szczególną ostrożność ze zmiennymi klas w środowisku wielowątkowym , zgodnie z komentarzem dmarkow.
źródło
ruby class << self end
robi blok, a konkretnie operator <<.class << self
zobacz to@
- Zmienna instancji klasy@@
- Zmienna klasy, w niektórych przypadkach nazywana także zmienną statycznąZmienna klasy to zmienna, która jest wspólna dla wszystkich instancji klasy. Oznacza to, że dla wszystkich obiektów utworzonych z tej klasy istnieje tylko jedna wartość zmiennej. Jeśli jedna instancja obiektu zmieni wartość zmiennej, ta nowa wartość zasadniczo zmieni się dla wszystkich innych instancji obiektu.
Inny sposób myślenia o zmiennych klasowych to zmienne globalne w kontekście pojedynczej klasy. Zmienne klas są deklarowane poprzez poprzedzenie nazwy zmiennej dwoma
@
znakami (@@
). Zmienne klasy muszą zostać zainicjowane w czasie tworzeniaźródło
@@
oznacza zmienną klasową, tzn. można ją dziedziczyć.Oznacza to, że jeśli utworzysz podklasę tej klasy, odziedziczy ona zmienną. Więc jeśli masz klasę
Vehicle
ze zmienną class,@@number_of_wheels
to jeśli utworzyszclass Car < Vehicle
klasę, to również będzie miała zmienną class@@number_of_wheels
źródło
Vehicle
ze zmienną class,@@number_of_wheels
to jeśli utworzysz zmienną klasową,class Car < Vehicle
to również będzie ona zawierała zmienną klasy@@number_of_wheels
class Vehicle
with@number_of_wheels
, toclass Car < Vehicle
będę miał również zmienną wystąpienia o nazwie@number_of_wheels
. Kluczowa różnica w stosunku do zmiennych klasowych polega na tym, że klasy mają tę samą zmienną, np. Zmiana jednej powoduje zmianę pozostałych.@ i @@ w modułach również działają inaczej, gdy klasa rozszerza lub zawiera ten moduł.
Tak biorąc
Następnie otrzymujesz wyniki poniżej pokazane jako komentarze
Więc używaj @@ w modułach dla zmiennych, które chcesz, aby były wspólne dla wszystkich ich zastosowań, a @ w modułach dla zmiennych, które chcesz osobno dla każdego kontekstu użycia.
źródło
Odpowiedzi są częściowo poprawne, ponieważ @@ jest w rzeczywistości zmienną klasową, która jest według hierarchii klas, co oznacza, że jest wspólna dla klasy, jej instancji i jej klas podrzędnych oraz ich instancji.
To wyjdzie
Jest więc tylko jedna ta sama zmienna @@ dla klas Person, Student i Graduate, a wszystkie metody klas i instancji tych klas odwołują się do tej samej zmiennej.
Istnieje inny sposób definiowania zmiennej klasy, która jest zdefiniowana w obiekcie klasy (pamiętaj, że każda klasa jest w rzeczywistości instancją czegoś, co w rzeczywistości jest klasą Class, ale jest to inna historia). Używasz notacji @ zamiast @@, ale nie możesz uzyskać dostępu do tych zmiennych z metod instancji. Musisz mieć opakowania metod klas.
Tutaj @people jest pojedyncza na klasę, a nie w hierarchii klas, ponieważ w rzeczywistości jest to zmienna przechowywana w każdej instancji klasy. Oto wynik:
Jedną ważną różnicą jest to, że nie można uzyskać dostępu do tych zmiennych klas (lub zmiennych instancji klasy, które można powiedzieć) bezpośrednio z metod instancji, ponieważ @people w metodzie instancji odwołuje się do zmiennej instancji tej konkretnej instancji klas Person, Student lub Graduate .
Tak więc, podczas gdy inne odpowiedzi poprawnie stwierdzają, że @myvariable (z pojedynczą notacją @) jest zawsze zmienną instancji, nie musi to oznaczać, że nie jest to pojedyncza zmienna wspólna dla wszystkich instancji tej klasy.
źródło