5
class Something
  @b = [4432]
  def screen
    puts @b.class
  end
end
s = Something.new
s.screen

输出'Nilclass'。想知道,为什么在类中定义的实例变量总是 NilClass 的一部分?

4

6 回答 6

11

实例变量属于一个对象(又名实例),这就是为什么它们被称为实例变量。每个实例都有自己的实例变量。

在您的情况下,有两个对象:(Something它是 的一个实例Class)和s(它是 的一个实例Something)。这两个对象中的每一个都有自己的一组实例变量。Something有一个名为的实例变量@b指向[4432]. s没有命名实例变量@b,因为您从未分配给它,并且未初始化的实例变量评估为nil.

于 2013-10-09T10:32:24.687 回答
4

你需要这样设置:

class Something
  def initialize
    @b = [4432]
  end

  def screen
    puts @b.class
  end
end

你这样做的方式,变量属于Something类本身,而不是它的实例。观察:

class Something
  @b = [4432]
end


s = Something.new
s.instance_variable_get(:@b) # => nil # !> instance variable @b not initialized

Something.instance_variable_get(:@b) # => [4432]
于 2013-10-09T10:14:21.600 回答
3

通常,实例变量必须在构造函数中定义,而在 ruby​​ 中,默认构造函数是初始化的,语法是

定义初始化

#these 是 ruby​​ 中的默认构造函数,因此当我们在构造函数中定义 insatnce 变量以及创建类的实例时,该实例/对象将包含实例变量的副本

最重要的是,尽管实例/对象包含实例变量,但实例/对象无法访问它,为什么因为默认情况下实例数据是私有的,所以为了访问它,我们需要为这些实例变量定义 getter 和 setter

class Something    
attr_accessor:b
def initialize
@b = [4432]
end
s=Something.new
puts"#{s.b}"
于 2013-10-09T18:40:26.677 回答
1

因为变量@b不存在!。例如,以下会产生与您看到的相同的结果。

class Something
  @b = [4432]
  def screen
    puts @a.class  #=> note @a which is non-existent
  end
end
s = Something.new
s.screen

然而

class Something
  @b = [4432]
  def screen
    puts @a.class
  end
  def self.screen
    puts @b.class
  end
end
s = Something.new

s.screen #=> NilClass    
Something.screen #=> Array
于 2013-10-09T10:26:50.403 回答
0

@Jörg W Mittag 的答案是正确的。我只是不想添加,在类中定义实例变量!= 在该类的实例中定义实例变量。要创建实例变量,在您的情况下,s您需要添加一个方法,当在类上调用initialize方法时会触发该方法。new

def initialize(b_value = default_value)
  @b = b_value
end
于 2015-02-16T20:49:39.697 回答
0

如果您在初始化程序之外初始化 @b,您希望 @b 范围是一个类变量,因此您必须将其称为 @@b :@@b 对于您的 Something Class 的所有实例具有相同的值

喜欢 :

class Somthing
  @@b = [4432] 
  def initialize
    #[...]
  end

  def screen
    puts @@b.class 
  end 
end
于 2013-10-09T12:42:48.030 回答