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

发布于 2024-09-25 01:26:31 字数 27 浏览 7 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅黛梨妆こ 2024-10-02 01:26:32

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


类变量 (@@)

让我们有一个带有类变量 @@i 的类 Foo,以及用于读取和写入 @ 的访问器@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 会改变它在两者中:

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

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

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

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:

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:

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

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

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:

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:

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

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

Bar.i = 2
p Foo.i    # => 1
p Bar.i    # => 2
痴者 2024-10-02 01:26:32

首先,您必须了解类也是实例——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!"

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

由于上述奇怪的行为,许多人说要避免使用类变量,而建议使用类实例变量。

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.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:

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.

番薯 2024-10-02 01:26:32

另外我想补充一点,您可以从类的任何实例访问类变量(@@),

class Foo
  def set_name
    @@name = 'Nik'
  end

  def get_name
    @@name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => Nik

但是您不能对类实例变量(@< /代码>)

class Foo
  def set_name
    @name = 'Nik'
  end

  def get_name
    @name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => nil

Also I want to add that you can get access to the class variable (@@) from any instance of the class

class Foo
  def set_name
    @@name = 'Nik'
  end

  def get_name
    @@name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => Nik

But you can't do the same for the class instance variable(@)

class Foo
  def set_name
    @name = 'Nik'
  end

  def get_name
    @name
  end
end


a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => nil
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文