local,instance和class变量之间有什么区别?

时间:2013-01-02 19:17:56

标签: ruby instance-variables local-variables class-variables

  

可能重复:
  Difference between class variables and class instance variables?

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

  1. 什么是实例变量?
  2. 什么是类实例变量?
  3. variable@instance_var@class_instance_var之间的区别是什么?
  4. 我试着阅读不同博客中的一些帖子,但我仍然不明白。任何帮助将不胜感激。

5 个答案:

答案 0 :(得分: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的一个实例)。所以它永远存在于类对象中,因为你永远无法真正摆脱声明的类。

答案 1 :(得分: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,则实例栏的值也会更改。

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会同时影响两个实例。这就是类变量的美(和恐怖)。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

实例变量是在类实例化时定义的。假设您有一个类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

答案 4 :(得分:1)