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

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

在阅读Ruby书时,我似乎错过了变量篇。 现在我似乎无法理解以下事情:

  1. 什么是实例变量?
  2. 什么是类实例变量?
  3. variable @instance_var@class_instance_var之间有什么区别?

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

什么是实例变量?

它是一个变量,具有与此类实例相关的特定值。 例如, 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在实例上@instance_var存在。 只要实例持续存在,它所拥有的实例变量也将如此。 只要Person实例存在,该实例将具有@name

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

变量类型会影响范围

网上有许多规范的解释,以及其他关于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会同时影响两个实例。 这就是类变量的美(和恐怖)。

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

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