请帮助我理解班级实例变量。
@@是一个类变量,它等同于类实例中的实例变量(@)。
但是在类级别上使用什么是实例变量(@)?如果它为类实例添加了一个定义,为什么不在初始化器中定义它呢?
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
答案 0 :(得分:2)
在你的回答中,你不输出类级实例变量。除了通常的语法(@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
答案 1 :(得分:1)
希望这个例子能解释@(实例)和@@(类)变量之间的区别。
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