什么是前面带有双 at 符号 ( @@) 的 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
双 at 符号是什么@@意思,它与单 at 符号有何不同?
带有前缀的变量@是 实例变量 ,而带有前缀的变量@@是 类变量 。查看以下示例;它的输出在行尾的注释中puts:
@
puts
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在类之间共享;在 one 的实例中设置值会更改该类的所有其他实例甚至子类的值,其中名为 的变量@shared与 one@不会是。
@@shared
@shared
[更新]
正如 Phrogz 在评论中提到的,在 Ruby 中使用 类本身 的实例变量来跟踪类级数据是一种常见的习惯用法。这可能是一个棘手的主题,需要围绕这个主题进行大量阅读,但可以将其视为修改Class类,而 只是Class修改您正在使用的类的实例。一个例子:
Class
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% 运行;我上面链接的文章有很多关于这个主题的附加信息。
Square
nil
另请记住,与大多数数据一样,根据 dmarkow 的评论,您应该非常小心多线程环境中的类变量。