@variable在Ruby中是什么意思?
什么是前面带有双at符号(@variable在Ruby中是什么意思?,ruby,syntax,instance-variables,class-variables,Ruby,Syntax,Instance Variables,Class Variables,什么是前面带有双at符号(@)的Ruby变量?我对前面带有at符号的变量的理解是,它是一个实例变量,在PHP中是这样的: PHP版本 class Person { public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } }
@
)的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符号有何不同?@
表示类变量,即它可以继承
这意味着,如果您创建该类的子类,它将继承该变量。因此,如果您有一个class
Vehicle
带有class变量@@number\u of_wheels
,那么如果您创建一个classCar
,那么它也会有class变量@@number\u of_wheels一个前缀为@
的变量是一个实例变量,而前缀为@
的是类变量。看看下面的例子;其输出在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
我包括了Square
示例(输出nil
),以证明这可能不会像您预期的那样100%地表现出来;在这个问题上,政府有很多额外的信息
此外,请记住,与大多数数据一样,根据dmarkow的评论,您应该非常小心地使用类中的类变量。@
-类的实例变量
@
-类变量,在某些情况下也称为静态变量
类变量是在类的所有实例之间共享的变量。这意味着从这个类实例化的所有对象只存在一个变量值。如果一个对象实例更改了变量的值,那么对于所有其他对象实例,该新值实际上都会更改
另一种思考类变量的方式是在单个类的上下文中作为全局变量。
类变量是通过在变量名前面加上两个@
字符(@
)来声明的。类变量必须在创建时初始化,当类扩展或包含模块时,模块中的@也会以不同方式工作
如此给定
module A
@a = 'module'
@@a = 'module'
def get1
@a
end
def get2
@@a
end
def set1(a)
@a = a
end
def set2(a)
@@a = a
end
def self.set1(a)
@a = a
end
def self.set2(a)
@@a = a
end
end
然后,您会得到下面显示为注释的输出
class X
extend A
puts get1.inspect # nil
puts get2.inspect # "module"
@a = 'class'
@@a = 'class'
puts get1.inspect # "class"
puts get2.inspect # "module"
set1('set')
set2('set')
puts get1.inspect # "set"
puts get2.inspect # "set"
A.set1('sset')
A.set2('sset')
puts get1.inspect # "set"
puts get2.inspect # "sset"
end
class Y
include A
def doit
puts get1.inspect # nil
puts get2.inspect # "module"
@a = 'class'
@@a = 'class'
puts get1.inspect # "class"
puts get2.inspect # "class"
set1('set')
set2('set')
puts get1.inspect # "set"
puts get2.inspect # "set"
A.set1('sset')
A.set2('sset')
puts get1.inspect # "set"
puts get2.inspect # "sset"
end
end
Y.new.doit
因此,在模块中使用@作为所有用途的通用变量,在模块中使用@作为每个用途上下文的独立变量。答案部分正确,因为@实际上是每个类层次结构的类变量,意味着它由一个类共享,它的实例及其子类及其实例
class Person
@@people = []
def initialize
@@people << self
end
def self.people
@@people
end
end
class Student < Person
end
class Graduate < Student
end
Person.new
Student.new
puts Graduate.people
班级人员
@@人=[]
def初始化
@@我不认识的人,但我感觉它在盯着我。我现在有点害怕用Ruby编写代码…TL;公共灾难恢复:100次中有99次,我会在self
方法中使用“类实例”变量(@
),而不是类变量(@
)。请参阅下面答案中的一系列原因。这意味着,如果您创建该类的子类,它将继承该变量。因此,如果您有一个类车辆
和一个类变量车轮数量
,那么如果您创建一个类车辆
,那么它也将有一个类变量@@number of of of the wheels
,如果我有一个类车辆
和@number of the wheels
,然后class Car
还将有一个名为@number\u of_wheels
的实例变量。类变量的关键区别在于类具有相同的变量,例如,改变一个会改变另一个。如果您包含代码,说明如何在类级别使用实例变量来跟踪类级别的数据,而不出现子类之间共享数据的“奇怪”行为,那么这个答案将是完美的。我还想指出,在多线程环境中,类变量可能是危险的/不可靠的(例如Rails)嗯……在某种程度上,它听起来像PHP中的静态变量,但继承部分是不同的。我不认为PHP有与此完全相同的东西。我不明白对于那些对类感到困惑的人来说,ruby类有什么不正确的地方。@myvariable从来不是“该类所有实例的单一共享变量”。它是仅具有该对象作用域的一个对象的实例变量。如果该对象不提供该变量的访问器,则其他对象(即使是声明该变量的类的实例)将无权访问该变量。这种情况实际上与访问实例的能力没有区别属于任何其他对象的变量。
class Person
@@people = []
def initialize
@@people << self
end
def self.people
@@people
end
end
class Student < Person
end
class Graduate < Student
end
Person.new
Student.new
puts Graduate.people
#<Person:0x007fa70fa24870>
#<Student:0x007fa70fa24848>
class Person
def initialize
self.class.add_person self
end
def self.people
@people
end
def self.add_person instance
@people ||= []
@people << instance
end
end
class Student < Person
end
class Graduate < Student
end
Person.new
Person.new
Student.new
Student.new
Graduate.new
Graduate.new
puts Student.people.join(",")
puts Person.people.join(",")
puts Graduate.people.join(",")
#<Student:0x007f8e9d2267e8>,#<Student:0x007f8e9d21ff38>
#<Person:0x007f8e9d226158>,#<Person:0x007f8e9d226608>
#<Graduate:0x007f8e9d21fec0>,#<Graduate:0x007f8e9d21fdf8>