Какие переменные Ruby начинаются с двойного в знаках ( @@
)? Мое понимание переменной, которой предшествует знак at, заключается в том, что это переменная экземпляра, как в PHP:
Версия PHP
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Рубиновый эквивалент
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
Что означает двойное в знаке @@
, и как оно отличается от единственного в знаке?
@
внутриself
методов), а не переменные класса (@@
). Смотрите список причин, почему в ответах ниже.Ответы:
Переменная префикс
@
является переменной экземпляра , в то время как один префикс@@
является переменной класса . Посмотрите на следующий пример; его вывод находится в комментариях в концеputs
строк:Вы можете видеть, что
@@shared
разделено между классами; установка значения в экземпляре one изменяет значение для всех других экземпляров этого класса и даже дочерних классов, где не будет переменной с именем@shared
, с одним@
.[Обновить]
Как упоминает Phrogz в комментариях, в Ruby распространена идиома - отслеживать данные уровня класса с помощью переменной экземпляра самого класса . Это может быть сложным предметом, чтобы обернуть ваше внимание, и есть много дополнительного чтения по этому вопросу, но подумайте об этом как о модификации
Class
класса, но только о экземпляреClass
класса, с которым вы работаете. Пример:Я включил
Square
пример (который выводитnil
), чтобы продемонстрировать, что это может не вести себя на 100%, как вы ожидаете; В статье, на которую я ссылался выше, есть много дополнительной информации по этому вопросу.Также имейте в виду, что, как и в случае с большинством данных, вы должны быть предельно осторожны с переменными класса в многопоточной среде , согласно комментарию dmarkow.
источник
ruby class << self end
делает блок, особенно оператор <<.class << self
видят это@
- переменная экземпляра класса@@
- переменная класса, в некоторых случаях также называемая статической переменнойПеременная класса - это переменная, которая используется всеми экземплярами класса. Это означает, что существует только одно значение переменной для всех объектов, созданных из этого класса. Если один экземпляр объекта изменяет значение переменной, это новое значение существенно изменится для всех остальных экземпляров объекта.
Другой способ мышления о переменных класса - это глобальные переменные в контексте одного класса. Переменные класса объявляются префиксом имени переменной двумя
@
символами (@@
). Переменные класса должны быть инициализированы во время созданияисточник
@@
обозначает переменную класса, т.е. она может быть унаследована.Это означает, что если вы создадите подкласс этого класса, он унаследует переменную. Так что, если у вас есть класс
Vehicle
с переменной класса,@@number_of_wheels
то, если вы создаете,class Car < Vehicle
то он тоже будет иметь переменную класса@@number_of_wheels
источник
Vehicle
с переменной класса,@@number_of_wheels
то, если вы создадите его, уclass Car < Vehicle
него тоже будет переменная класса@@number_of_wheels
class Vehicle
с@number_of_wheels
, тоclass Car < Vehicle
также будет иметь имя переменной экземпляра@number_of_wheels
. Основное различие с переменными класса состоит в том, что классы имеют одну и ту же переменную, например, изменение одной изменяет другие.Модули @ и @@ in также работают по-разному, когда класс расширяет или включает этот модуль.
Так дано
Тогда вы получите результаты, показанные ниже в виде комментариев
Поэтому используйте @@ в модулях для переменных, которые вы хотите использовать для всех их применений, и используйте @ в модулях для переменных, которые вы хотите использовать отдельно для каждого контекста использования.
источник
Ответы частично верны, потому что @@ на самом деле является переменной класса для каждой иерархии классов, что означает, что она является общей для класса, его экземпляров и классов-потомков и их экземпляров.
Это будет выводить
Таким образом, существует только одна и та же переменная @@ для классов Person, Student и Graduate, и все методы классов и экземпляров этих классов ссылаются на одну и ту же переменную.
Существует другой способ определения переменной класса, которая определена для объекта класса (помните, что каждый класс на самом деле является экземпляром чего-то, что на самом деле является классом Class, но это другая история). Вы используете @ нотацию вместо @@, но вы не можете получить доступ к этим переменным из методов экземпляра. Вы должны иметь обертки метода класса.
Здесь @people является отдельным для класса вместо иерархии классов, потому что это фактически переменная, хранящаяся в каждом экземпляре класса. Это вывод:
Одно важное отличие состоит в том, что вы не можете получить доступ к этим переменным класса (или к переменным экземпляра класса, которые вы можете сказать) напрямую из методов экземпляра, поскольку @people в методе экземпляра будет ссылаться на переменную экземпляра этого конкретного экземпляра классов Person, Student или Graduate. ,
Таким образом, в то время как другие ответы правильно утверждают, что @myvariable (с одиночной нотацией @) всегда является переменной экземпляра, это не обязательно означает, что это не одна общая переменная для всех экземпляров этого класса.
источник