【问题标题】:Instance variables in rubyruby 中的实例变量
【发布时间】:2013-02-01 06:58:53
【问题描述】:
 class Sample
   attr_accessor :x,:y

   def initialize 
     @x = "x"
     y = "y"     
   end
 end     

 Sample.new.instance_variables  => [:@x] 

class Sample
  attr_accessor :x,:y

  def initialize 
     @x = "x"
     self.y = "y"     
  end
end  

Sample.new.instance_variables => [:@x, :@y] 

谁能告诉我这里发生了什么。为什么 y 第二次是 instance_variable?

【问题讨论】:

  • 在第一个示例中,如果您分配:@y=1,那么您也将获得 @y 作为 ivar。我猜 Ruby 正在 attr_accessor 中进行优化,并且在您专门分配给它之前不会创建 ivar。
  • 和 @Zabba :在您为其赋值之前,变量不存在。请看stackoverflow.com/questions/13850971/…

标签: ruby


【解决方案1】:

attr_accessor :y 定义的方法大致相当于

def y
  @y
end

def y=(val)
  @y = val
end

因此,当您分配给self.y 时,由于attr_accessor 宏,您正在分配给一个实例变量

【讨论】:

  • 小心术语。 self.y = 1不是分配给 ivar
  • “分配给实例变量由于 ...”。我认为这清楚地表明宏是你拥有 ivar 的原因,而不是赋值:|
【解决方案2】:

为什么不呢? self 是一个实例,y 是一个实例变量。在第一个示例中,y 只是一个普通的本地变量。

【讨论】:

    【解决方案3】:

    这一行

    attr_accessor :y
    

    创建几个方法

    def y
      @y
    end
    
    def y= val
      @y = val
    end
    

    因此,当您调用 y= 方法时,@y 实例变量会立即生效。在第二个 sn-p 中,您正确调用 y= 方法。但在第一个中,您只需创建一个未使用的局部变量 y(不调用 setter 方法,也不创建 ivar)。

    【讨论】:

    • 重要的是要注意,从历史上看,attr_accessor 的基准测试速度比这些等效方法快,它们是基于 C 的优化而不是可执行代码,因此尽可能使用 attr_ 声明而不是自己写。
    猜你喜欢
    • 2014-09-21
    • 1970-01-01
    • 2010-12-05
    • 2014-10-23
    • 1970-01-01
    • 2013-11-26
    • 2021-07-29
    • 2013-03-24
    相关资源
    最近更新 更多