类变量和类实例变量之间的区别?

时间:2022-02-16 13:21:12

Can anyone tell me about the difference between class variables and class instance variables?

有人能告诉我类变量和类实例变量之间的区别吗?

2 个解决方案

#1


138  

A class variable (@@) is shared among the class and all of its descendants. A class instance variable (@) is not shared by the class's descendants.

类变量(@@)在类及其所有子代之间共享。类实例变量(@)不会被类的后代共享。


Class variable (@@)

类变量(@@)

Let's have a class Foo with a class variable @@i, and accessors for reading and writing @@i:

让我们有一个类Foo,它有一个类变量@@i,以及读写@@i的访问器:

class Foo

  @@i = 1

  def self.i
    @@i
  end

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

end

And a derived class:

和一个派生类:

class Bar < Foo
end

We see that Foo and Bar have the same value for @@i:

我们看到Foo和Bar的值与@@i相同:

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

And changing @@i in one changes it in both:

将@@i更改为一个,将两者都更改为:

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

Class instance variable (@)

类的实例变量(@)

Let's make a simple class with a class instance variable @i and accessors for reading and writing @i:

让我们用一个类实例变量@i和读写@i的访问器创建一个简单的类:

class Foo

  @i = 1

  def self.i
    @i
  end

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

end

And a derived class:

和一个派生类:

class Bar < Foo
end

We see that although Bar inherits the accessors for @i, it does not inherit @i itself:

我们看到,Bar虽然继承了@i的访问器,但并没有继承@i本身:

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

We can set Bar's @i without affecting Foo's @i:

我们可以设置Bar的@i而不影响Foo的@i:

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

#2


60  

First you must understand that classes are instances too -- instances of the Class class.

首先,您必须理解类也是实例——类的实例。

Once you understand that, you can understand that a class can have instance variables associated with it just as a regular (read: non-class) object can.

一旦您理解了这一点,您就可以理解一个类可以有与它相关联的实例变量,就像一个普通的(读:非类)对象可以那样。

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!"

Note that an instance variable on Hello is completely unrelated to and distinct from an instance variable on an instance of Hello

注意,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!"

A class variable on the other hand is a kind of combination of the above two, as it accessible on Hello itself and its instances, as well as on subclasses of Hello and their instances:

另一方面,类变量是上述两个变量的一种组合,它可以在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!"

Many people say to avoid class variables because of the strange behaviour above, and recommend the use of class instance variables instead.

许多人说要避免类变量,因为上面的奇怪行为,并建议使用类实例变量。

#1


138  

A class variable (@@) is shared among the class and all of its descendants. A class instance variable (@) is not shared by the class's descendants.

类变量(@@)在类及其所有子代之间共享。类实例变量(@)不会被类的后代共享。


Class variable (@@)

类变量(@@)

Let's have a class Foo with a class variable @@i, and accessors for reading and writing @@i:

让我们有一个类Foo,它有一个类变量@@i,以及读写@@i的访问器:

class Foo

  @@i = 1

  def self.i
    @@i
  end

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

end

And a derived class:

和一个派生类:

class Bar < Foo
end

We see that Foo and Bar have the same value for @@i:

我们看到Foo和Bar的值与@@i相同:

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

And changing @@i in one changes it in both:

将@@i更改为一个,将两者都更改为:

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

Class instance variable (@)

类的实例变量(@)

Let's make a simple class with a class instance variable @i and accessors for reading and writing @i:

让我们用一个类实例变量@i和读写@i的访问器创建一个简单的类:

class Foo

  @i = 1

  def self.i
    @i
  end

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

end

And a derived class:

和一个派生类:

class Bar < Foo
end

We see that although Bar inherits the accessors for @i, it does not inherit @i itself:

我们看到,Bar虽然继承了@i的访问器,但并没有继承@i本身:

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

We can set Bar's @i without affecting Foo's @i:

我们可以设置Bar的@i而不影响Foo的@i:

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

#2


60  

First you must understand that classes are instances too -- instances of the Class class.

首先,您必须理解类也是实例——类的实例。

Once you understand that, you can understand that a class can have instance variables associated with it just as a regular (read: non-class) object can.

一旦您理解了这一点,您就可以理解一个类可以有与它相关联的实例变量,就像一个普通的(读:非类)对象可以那样。

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!"

Note that an instance variable on Hello is completely unrelated to and distinct from an instance variable on an instance of Hello

注意,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!"

A class variable on the other hand is a kind of combination of the above two, as it accessible on Hello itself and its instances, as well as on subclasses of Hello and their instances:

另一方面,类变量是上述两个变量的一种组合,它可以在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!"

Many people say to avoid class variables because of the strange behaviour above, and recommend the use of class instance variables instead.

许多人说要避免类变量,因为上面的奇怪行为,并建议使用类实例变量。