【问题标题】:What is the difference between local, instance, and class variables? [duplicate]局部变量、实例变量和类变量有什么区别? [复制]
【发布时间】:2012-12-17 03:50:13
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你在stackoverflow.com/questions/3802540/…这里读到答案了吗?
  • 1) @@cv 是类变量,而不是类实例变量。 @class_inst_var 是定义在类主体中的实例变量,被视为类的实例,以及外部方法定义。 2)实例变量对每个实例都有一个值的信念来自静态语言。在 Ruby 中,变量只有在您为其赋值时才会存在。请在此处阅读演示:stackoverflow.com/questions/13850971/…

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


【解决方案1】:

变量类型影响范围

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 实例变量不必在类被实例化时定义。它也可以在类实例化之后定义。
    【解决方案3】:

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

    【讨论】:

    • 如果我错了,请纠正我,但@var有两种类型
    • @sannySin afaik 只有一个
    • 1) @@cv 是类变量,而不是类实例变量。 @class_inst_var 是定义在类主体中的实例变量,被视为类的实例,以及外部方法定义。 2) 实例变量对每个实例都有一个值的信念来自静态语言。在 Ruby 中,变量只有在您为其赋值后才会存在。请在此处阅读演示:stackoverflow.com/questions/13850971/…
    【解决方案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 的一个实例)。所以它将永远存在于类对象中,因为你永远无法真正摆脱已声明的类。

    【讨论】:

      【解决方案5】:
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 2016-01-17
      • 2021-10-22
      • 2013-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多