@@ variable在Ruby中意味着什么?

And*_*rew 153 ruby syntax instance-variables class-variables

什么是Ruby变量,在符号(@@)前面加上double ?我对一个带有at符号的变量的理解是它是一个实例变量,在PHP中是这样的:

PHP版本

class Person {

    public $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ruby相当于

class Person

    def set_name(name)
        @name = name
    end

    def get_name()
        @name
    end
end
Run Code Online (Sandbox Code Playgroud)

双重标志@@是什么意思,它与单个标志有什么不同?

Mic*_*ley 231

前缀的变量@实例变量,而前缀@@变量类变量.看看下面的例子; 它的输出位于行尾的注释中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
Run Code Online (Sandbox Code Playgroud)

你可以看到@@shared在类之间共享; 在一个实例中设置值会更改该类的所有其他实例的值,甚至是子类,其中一个名称为@shared1 的变量@不会.

[更新]

正如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
Run Code Online (Sandbox Code Playgroud)

我包含了Square示例(输出nil),以证明这可能不像您期望的那样100%表现; 我上面链接文章有很多关于这个主题的额外信息.

另请注意,与大多数数据一样,您应该在多线程环境中对类变量非常小心,根据dmarkow的评论.

  • 我不明白```ruby class << self end```块是什么,特别是<<运算符. (5认同)
  • 我还要指出,在多线程环境中,类变量可能是危险的/不可靠的(例如Rails) (3认同)
  • 恕我直言,如果您包含显示如何在类级别使用实例变量来跟踪类级别数据而无需在子类之间共享数据的“奇怪”行为的代码,那么这个答案将是完美的。 (2认同)

Sha*_*nak 36

@- 类的实例变量
@@- 类变量,在某些情况下也称为静态变量

类变量是在类的所有实例之间共享的变量.这意味着对于从此类实例化的所有对象,只存在一个变量值.如果一个对象实例更改了该变量的值,则该新值将基本上针对所有其他对象实例进行更改.

思考类变量的另一种思考方式是在单个类的上下文中作为全局变量.通过在变量名前加上两个@字符(@@)来声明类变量.必须在创建时初始化类变量


Far*_*gam 10

@@ 表示一个类变量,即它可以被继承.

这意味着如果您创建该类的子类,它将继承该变量.因此,如果你有一个Vehicle带有类变量的类,@@number_of_wheels那么如果你创建了一个类,class Car < Vehicle那么它也会有类变量@@number_of_wheels

  • 如果我有一个带有`@ number_of_wheels`的`class Vehicle`,那么`class Car <Vehicle`也会有一个名为`@ number_of_wheels`的实例变量.类变量的主要区别在于类具有*相同的*变量,例如,更改一个变更其他变量. (12认同)