1

可能重复:
类变量和类实例变量之间的区别?

在阅读 Ruby 书籍时,我似乎错过了变量章节。现在我似乎无法理解以下内容:

  1. 什么是实例变量?
  2. 什么是类实例变量?
  3. variablea和@instance_var有什么区别@class_instance_var

我试图阅读不同博客中的一些帖子,但我仍然不明白。任何帮助,将不胜感激。

4

5 回答 5

4

什么是实例变量?

它是一个具有与该类实例相关的独立值的变量。例如,一个Person类可以有@name@age作为实例变量。所有的实例Person都有一个名字和年龄,但是每个实例对于这些东西都有不同的值。


什么是类实例变量?

这有点奇怪,但你必须意识到这个Person类本身就是Class. 所以它也可以有实例变量。这通常用于配置类。就像向一个类添加一个 API 密钥,以便可以使用该数据创建所有实例。

class PersonFetcher

  # class method can set class instance variables
  def self.set_api_key(key)
    @api_key = key
  end

  # instance method sets instance variables
  def set_name(name)
    @name = name
  end

end

变量@instance_var 和@class_instance_var 有什么区别?

它是如何持续存在的。

variable是本地的。它只是对对象的引用。一旦没有代码或对象引用此值,它就会通过垃圾收集被销毁。只有继续使用它才会持续存在。

@instance_var持续存在于实例上。只要实例存在,它所拥有的实例变量也会存在。只要Person实例存在,该实例就会有一个@name.

@class_instance_var持续存在于类对象上(记住是 的一个实例Class)。因此它将永远存在于类对象中,因为您永远无法真正摆脱已声明的类。

于 2013-01-02T19:35:10.793 回答
4

变量类型影响范围

网络上有很多规范的解释,在 SO 的其他地方也有一些深入的解释,但我将与您分享另一种看待它的方式:变量范围。

局部变量

局部变量通常用于方法中,并且仅具有局部范围。例如:

def foo
  # bar is only in scope within #foo.
  bar = true
end

每当方法返回时,bar变量就会超出范围。

实例变量

实例变量可用于绑定到对象实例的任何方法。作为一个实际问题,这通常会在某个实例化的类对象中赋予它范围。例如:

class Foo
  def bar
    @quux = true
  end

  def baz
    @quux == true
  end
end

foo = Foo.new

虽然@quux 并不是真正的全局,但它对绑定到我们实例化的foo对象的所有方法都是可见的,而无需将其作为参数显式传递。

类变量

类变量在类的所有实例之间共享。这意味着如果您从实例 foo 更改 @@bar,那么实例 bar 的值也会更改。

class Foo
  @@bar = true

  def show_class_variable
    @@bar
  end

  def bar= value
    @@bar = value
  end
end

foo = Foo.new
bar = Foo.new

foo.show_class_variable # => true
bar.show_class_variable # => true

foo.bar = false
foo.show_class_variable # => false
bar.show_class_variable # => false

请注意更改 @@bar 如何同时影响两个实例。这就是类变量的美妙之处(也是可怕之处)。

于 2013-01-02T20:04:13.227 回答
1

变量是方法的局部变量,因此应该在此方法中定义,实例变量是为给定类的对象(实例)定义的变量,并且每个对象都有一个值。类实例变量用@@(与您提到的单个变量相反)表示,并在类的所有@实例之间共享,如果其中一个实例更改其值,则所有实例都将看到新值。类实例变量等价于 c++ 和 java 的静态成员变量,实例变量等价于非静态变量。

于 2013-01-02T19:28:33.197 回答
1

实例变量是在类被实例化时定义的。假设你有一个 class Point,它定义了一些局部变量和方法。

class Point
  def initialize(x,y)
     @x, @y = x, y
  end

  def add(other)
     Point.new(@x + other, @y + other)
  end
end

当您实例化定义的类并将其分配给一个变量时,您正在实例化该类:

point = Point.new(2,2)

..这是实例变量。

Ruby 中的类是对象,并且可以像其他对象一样具有实例变量。在定义内部class但在实例方法定义外部定义的实例变量称为类实例变量

例子:

class Point 
  @n = 0
  @total_x = 0
  @total_y = 0

  def initialize(x,y)
     @x,@y = x,y
  end
end

还有第三种,即class variable。类变量对类方法和类的实例方法是可见的,并由其共享。与实例变量一样,类变量可以被类的实现使用,但它们对类的用户是不可见的。类变量以@@. 实例变量总是参考 评估self。这与类变量有很大的不同,类变量总是参考由封闭class定义语句创建的类对象进行评估。使用相同的示例,我们可以重写代码如下:

class Point
   @@n = 0
   @@total_x = 0
   @@total_y = 0

   def initialize(x,y)
      @x,@y = x, y
      @@n += 1
   end

   def self.report
      puts "Number of points: #{@@n.to_s}"
   end
end
于 2013-01-02T19:34:09.880 回答
1

您可以通过简单的谷歌搜索找到很多文章:

http://blog.codegram.com/2011/4/understanding-class-instance-variables-in-ruby

http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

于 2013-01-02T19:35:02.907 回答