局部变量、实例变量和类变量之间的区别是什么



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

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

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

我试着在不同的博客上读一些帖子,但我仍然不明白。如有任何帮助,我们将不胜感激。

什么是实例变量?

它是一个变量,它有一个与类的这个实例相关的idependent值。例如,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的实例(。因此,它将永远存在于类对象中,因为您永远无法真正摆脱已声明的类。

变量类型影响范围

网络上有很多规范的解释,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是如何同时影响这两个实例的。这就是类变量的美妙之处(也是恐怖之处(。

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

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/

可变变量是方法的局部变量,因此应该在该方法中定义,实例变量是为给定类的对象(的实例(定义的变量,每个对象都有一个值。类实例变量用@@表示(与您提到的单个@相反(,并在类的所有实例之间共享,如果其中一个实例更改了其值,则所有实例都将看到新值。类实例变量与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

最新更新