小编典典

@@variable 在 Ruby 中是什么意思?

all

什么是前面带有双 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 符号有何不同?


阅读 127

收藏
2022-07-30

共1个答案

小编典典

带有前缀的变量@实例变量 ,而带有前缀的变量@@类变量 。查看以下示例;它的输出在行尾的注释中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@不会是。

[更新]

正如 Phrogz 在评论中提到的,在 Ruby 中使用 类本身
的实例变量来跟踪类级数据是一种常见的习惯用法。这可能是一个棘手的主题,需要围绕这个主题进行大量阅读,但可以将其视为修改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%
运行;我上面链接的文章有很多关于这个主题的附加信息。

另请记住,与大多数数据一样,根据 dmarkow 的评论,您应该非常小心多线程环境中的类变量。

2022-07-30