@@variable 在 Ruby 中是什么意思? [英] What does @@variable mean in Ruby?
问题描述
什么是 Ruby 变量前面带有 double at 符号 (@@
)?我对以 at 符号开头的变量的理解是它是一个实例变量,在 PHP 中是这样的:
What are Ruby variables preceded with double at signs (@@
)? My understanding of a variable preceded with an at sign is that it is an instance variable, like this in PHP:
PHP 版本
class Person {
public $name;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
Ruby 等价物
class Person
def set_name(name)
@name = name
end
def get_name()
@name
end
end
双符号 @@
是什么意思,它与单符号 at 有什么区别?
What does the double at sign @@
mean, and how does it differ from a single at sign?
推荐答案
以@
为前缀的变量是一个实例变量,而以@@为前缀的变量是一个实例变量
是一个类变量.查看以下示例;它的输出在 puts
行末尾的注释中:
A variable prefixed with @
is an instance variable, while one prefixed with @@
is a class variable. Check out the following example; its output is in the comments at the end of the puts
lines:
class Test
@@shared = 1
def value
@@shared
end
def value=(value)
@@shared = value
end
end
class AnotherTest < Test; end
t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2
x = Test.new
puts "x.value is #{x.value}" # 2
a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3
可以看到@@shared
在类之间是共享的;在一个实例中设置值会更改该类甚至子类的所有其他实例的值,其中名为 @shared
的变量和一个 @
不会
You can see that @@shared
is shared between the classes; setting the value in an instance of one changes the value for all other instances of that class and even child classes, where a variable named @shared
, with one @
, would not be.
[更新]
正如 Phrogz 在评论中提到的那样,在 Ruby 中使用实例变量在类本身跟踪类级数据是一种常见的习惯用法.这可能是一个棘手的主题,让您思考,并且有很多 关于这个主题的额外阅读,但认为它是修改Class
类,但仅Class 的实例代码> 你正在使用的类.一个例子:
As Phrogz mentions in the comments, it's a common idiom in Ruby to track class-level data with an instance variable on the class itself. This can be a tricky subject to wrap your mind around, and there is plenty of additional reading on the subject, but think about it as modifying the Class
class, but only the instance of the Class
class you're working with. An example:
class Polygon
class << self
attr_accessor :sides
end
end
class Triangle < Polygon
@sides = 3
end
class Rectangle < Polygon
@sides = 4
end
class Square < Rectangle
end
class Hexagon < Polygon
@sides = 6
end
puts "Triangle.sides: #{Triangle.sides.inspect}" # 3
puts "Rectangle.sides: #{Rectangle.sides.inspect}" # 4
puts "Square.sides: #{Square.sides.inspect}" # nil
puts "Hexagon.sides: #{Hexagon.sides.inspect}" # 6
我包含了 Square
示例(它输出 nil
)来证明这可能不会像您期望的 100% 一样;我上面链接的文章有很多额外的有关主题的信息.
I included the Square
example (which outputs nil
) to demonstrate that this may not behave 100% as you expect; the article I linked above has plenty of additional information on the subject.
还要记住,与大多数数据一样,您应该非常小心 中的类变量多线程环境,根据 dmarkow 的评论.
Also keep in mind that, as with most data, you should be extremely careful with class variables in a multithreaded environment, as per dmarkow's comment.
这篇关于@@variable 在 Ruby 中是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!