94

クラス変数とクラスインスタンス変数の違いについて教えてもらえますか?

4

3 に答える 3

157

クラス変数(@@)は、クラスとそのすべての子孫の間で共有されます。クラスインスタンス変数(@)は、クラスの子孫によって共有されません。


クラス変数(@@

クラス変数を持つクラスFooと、@@i読み取りおよび書き込み用のアクセサーを用意しましょう@@i

class Foo

  @@i = 1

  def self.i
    @@i
  end

  def self.i=(value)
    @@i = value
  end

end

そして派生クラス:

class Bar < Foo
end

FooとBarの値が同じであることがわかります@@i

p Foo.i    # => 1
p Bar.i    # => 1

そして@@i、1つで変更すると、両方で変更されます。

Bar.i = 2
p Foo.i    # => 2
p Bar.i    # => 2

クラスインスタンス変数(@

@iクラスインスタンス変数と読み取りおよび書き込み用のアクセサーを使用して、単純なクラスを作成しましょう@i

class Foo

  @i = 1

  def self.i
    @i
  end

  def self.i=(value)
    @i = value
  end

end

そして派生クラス:

class Bar < Foo
end

Barはのアクセサーを継承しますが、それ自体@iは継承しません。@i

p Foo.i    # => 1
p Bar.i    # => nil

@iFooに影響を与えることなくBarを設定できます@i

Bar.i = 2
p Foo.i    # => 1
p Bar.i    # => 2
于 2010-09-27T10:48:12.897 に答える
73

まず、クラスもインスタンス、つまりクラスのインスタンスであることを理解する必要がありますClass

それを理解すれば、通常の (非クラス) オブジェクトと同じように、クラスにインスタンス変数を関連付けることができることを理解できます。

Hello = Class.new

# setting an instance variable on the Hello class
Hello.instance_variable_set(:@var, "good morning!")

# getting an instance variable on the Hello class
Hello.instance_variable_get(:@var) #=> "good morning!"

のインスタンス変数は、のインスタンスのインスタンス変数とHelloはまったく無関係であり、区別されることに注意してください。Hello

hello = Hello.new

# setting an instance variable on an instance of Hello
hello.instance_variable_set(:@var, :"bad evening!")

# getting an instance variable on an instance of Hello
hello.instance_variable_get(:@var) #=> "bad evening!")

# see that it's distinct from @var on Hello
Hello.instance_variable_get(:@var) #=> "good morning!"

一方、クラス変数は、それ自体とそのインスタンス、およびそのサブクラスとそのインスタンスにアクセスできるため、上記の 2 つの組み合わせの一種HelloですHello

HelloChild = Class.new(Hello)
Hello.class_variable_set(:@@class_var, "strange day!")
hello = Hello.new
hello_child = HelloChild.new

Hello.class_variable_get(:@@class_var) #=> "strange day!"
HelloChild.class_variable_get(:@@class_var) #=> "strange day!"
hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!"
hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"

多くの人はclass variables、上記の奇妙な動作のために避けるように言い、class instance variables代わりに の使用を推奨します。

于 2010-09-27T10:54:29.570 に答える