【问题标题】:In Ruby, in the context of a class method, what are instance and class variables?在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量?
【发布时间】:2011-02-05 15:04:17
【问题描述】:

如果我有以下 Ruby 代码:

class Blah
  def self.bleh
    @blih = "Hello"
    @@bloh = "World"
  end
end

@blih 和 @@bloh 到底是什么? @blih 是 Blah 类中的实例变量,@@bloh 是 Blah 类中的类变量,对吗?是不是说@@bloh 是Blah 的类Class 中的一个变量?

【问题讨论】:

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


    【解决方案1】:

    以两个 at 符号为前缀的变量是类变量,可在类的实例和类方法中访问。

    例子:

    class CountEm
      @@children = 0
    
      def initialize
        @@children += 1
        @myNumber = @@children
      end
    
      def whoAmI
        "I'm child number #@myNumber (out of #@@children)"
      end
    
      def CountEm.totalChildren
        @@children
      end
    end
    
    c1 = CountEm.new
    c2 = CountEm.new
    c3 = CountEm.new
    c1.whoAmI              # -> "I'm child number 1 (out of 3)"
    c3.whoAmI              # -> "I'm child number 3 (out of 3)"
    CountEm.totalChildren  # -> 3
    

    示例取自link text

    【讨论】:

    • OP 了解什么是类变量,他在问从类方法中使用它们时它们会如何变化。
    • 我不确定,但如果是这种情况,我很抱歉。我的错。
    【解决方案2】:

    [为清楚起见进行了编辑]

    在您的示例设置中,@blih 在您的类方法范围之外将不可见,因为在类方法内部没有实例可以将实例变量绑定到它。

    说到术语,我会说“@@bloh 是 Blah 类中的 类变量”,而不是“Blah 类中的变量”。 “Class”类保持不变。

    【讨论】:

    • 有一个要附加的实例。类是类 Class 的实例,将在评估类定义时实例化。 > Bleh.instance_of?类 => 真
    • crudson 是正确的,@blih 是附加到类Blah 的实例变量。
    【解决方案3】:

    这种疯狂是有办法的……

    class Example
      @foo # class instance variable
      @@bar # class variable
    
      def fun1
        @baz # instance variable
      end
    end
    

    实例变量

    实例变量(示例中的@foo@baz)总是以@ 开头,并且它们总是属于自身所指的任何对象:要么类的对象,或表示类的 Class 对象。类定义或类方法中的实例变量引用与实例方法中的实例变量引用完全不同。

    继承
    因为实例变量不是由类定义的,所以它们与继承机制无关——它们只是在为它们赋值时创建。类实例变量,只是表示类的 Class 对象的实例变量,因此不会被继承。

    类变量

    类变量对类方法和类的实例方法以及类定义本身都是可见和共享的。类变量可以在实例方法、类方法和类定义本身中使用,在任何方法之外。 类变量总是根据封闭类定义语句创建的类对象进行评估

    类实例变量与实例变量

    类实例变量的一个缺点是它们不能像类变量那样在实例方法中使用。另一个缺点是可能会将它们与普通实例变量混淆。类实例变量优于类变量的一个优势在于,在对现有类进行子类化时类变量的令人困惑的行为:如果一个类使用类变量,那么任何子类都可以通过更改值来改变该类及其所有后代的行为共享类变量。这是使用类实例变量而不是类变量的有力论据。

    其中大部分来自优秀的"The Ruby Programming Language"

    【讨论】:

    • @banister:我倾向于不同意。我想我用加粗的两个句子专门回答了这个问题。我本可以把这些陈述放在没有其余部分的地方,但我认为它的用处不大。无论如何,这只是我的意见。
    【解决方案4】:

    人们似乎忽略了该方法是类方法。

    @blih 将是常量 Bleh 的类 Class 实例的实例变量。因此:

    irb(main):001:0> class Bleh
    irb(main):002:1>   def self.bleh
    irb(main):003:2>     @blih = "Hello"
    irb(main):004:2>     @@blah = "World"
    irb(main):005:2>   end
    irb(main):006:1> end
    => nil
    irb(main):007:0> Bleh.instance_variables
    => []
    irb(main):008:0> Bleh.bleh
    => "World"
    irb(main):009:0> Bleh.instance_variables
    => ["@blih"]
    irb(main):010:0> Bleh.instance_variable_get :@blih
    => "Hello"
    

    @@blah 将作为 Bleh 的类变量提供:

    irb(main):017:0> Bleh.class_variables
    => ["@@blah"]
    irb(main):018:0> Bleh.send :class_variable_get, :@@blah
    => "World"
    

    【讨论】:

      猜你喜欢
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 2013-11-26
      • 2013-03-24
      • 2014-09-21
      • 2012-06-23
      相关资源
      最近更新 更多