请帮助我理解类级实例变量。
@@是一个类变量,相当于类实例中的实例变量(@)。
但是,当在类级别上使用实例变量(@)时,它是什么?如果它将定义放在类实例中,那么为什么不在初始化器中定义它呢?
class MyClass
cattr_reader :class_variable
def self.new_instance(cv, cliv, iv)
@@class_variable = cv
@class_level_instance_variable = cliv
self.new(iv)
end
def initialize(iv)
@instance_variable = iv
end
def use
puts "class_var=#{self.class.class_variable.inspect}ninst_var=#{@instance_variable.inspect}ncliv=#{@class_level_instance_variable.inspect}"
end
end
c = []
c << MyClass.new_instance(1,2,3)
c[0].use
c << MyClass.new_instance(4,5,6)
c[1].use
c << MyClass.new_instance(7,8,9)
c[2].use
c[0].use
c[1].use
c[2].use
希望这个例子能解释@(instance)和@@(class)变量之间的区别。
class Animal
@@total_count = 0
def self.total_count
@@total_count
end
def initialize
@@total_count += 1
end
end
class Cat < Animal
end
Animal.new
Animal.new
Cat.new
Animal.total_count # => 3
Cat.total_count # => 3
正如您所看到的,@@变量是在类及其子级之间共享的。如果我真的想计算类的实例数量,我必须使用以下代码。
class Animal
class << self
attr_accessor :total_count
end
@total_count = 0
def self.total_count
@total_count
end
def initialize
self.class.total_count += 1
end
end
class Cat < Animal
@total_count = 0
end
Animal.new
Animal.new
Cat.new
Animal.total_count # => 2
Cat.total_count # => 1
在您的回答中,您不输出类级实例变量。除了通常的语法(@foo
)之外,还可以通过方法(instance_variable_get(:@foo)
)访问实例变量。您可以使用此方法读取其他对象的实例变量,而不仅仅是self
。
这是您的代码的修改版本
require 'active_support/core_ext'
class MyClass
cattr_reader :class_variable
def self.new_instance(cv, cliv, iv)
@@class_variable = cv
@class_level_instance_variable = cliv
self.new(iv)
end
def initialize(iv)
@instance_variable = iv
end
def use
puts "class_var=#{self.class.class_variable.inspect}"
puts "class inst var: #{self.class.instance_variable_get(:@class_level_instance_variable)}"
puts "inst_var=#{@instance_variable.inspect}"
end
end
c = []
c << MyClass.new_instance(1,2,3)
c << MyClass.new_instance(4,5,6)
c << MyClass.new_instance(7,8,9)
c[0].use
c[1].use
c[2].use
# >> class_var=7
# >> class inst var: 8
# >> inst_var=3
# >> class_var=7
# >> class inst var: 8
# >> inst_var=6
# >> class_var=7
# >> class inst var: 8
# >> inst_var=9
请看,类inst-var总是8(就像类var总是7一样)。这是因为在进行了所有修改之后才输出值。由于类级别的变量是共享的,最后一次修改获胜。
c << MyClass.new_instance(7,8,9)
如果您要从初始值设定项输出(就像在第一个版本的代码中一样),您会看到不同的结果。
# >> class_var=1
# >> class inst var: 2
# >> inst_var=3
# >> class_var=4
# >> class inst var: 5
# >> inst_var=6
# >> class_var=7
# >> class inst var: 8
# >> inst_var=9