【问题标题】:doubts regarding "||=" OR EQUALS operator in ruby [duplicate]关于红宝石中“||=”或等于运算符的疑问[重复]
【发布时间】:2014-08-06 18:43:48
【问题描述】:

我对 ruby​​ 中的 OR EQUALS (||=) 运算符有一些疑问。 ruby 解释器是如何实现的?这是一个代码示例:

class C
  def arr
    @num ||= []
  end
end

当我们在这种情况下使用 OR EQUALS 运算符时,第一次调用此方法会初始化变量并添加一个元素,这很好。当第二次调用arr 时,它如何知道数组中有一个元素..

【问题讨论】:

    标签: ruby operators equals core


    【解决方案1】:

    在 Ruby 中,有两个值被认为是逻辑错误。第一个是布尔值false,另一个是nil。任何非nil 且未明确false 的都是true。第一次使用该方法时,@numnil,它被视为 false 并且需要评估 ||= 的逻辑 or 部分并最终将空数组分配给 @num。由于现在不是nil,它等同于true。因为无论x 是什么,true || x 都是真的,所以在未来的调用中,Ruby 会短路评估并且不执行分配。

    【讨论】:

      【解决方案2】:

      一般来说x ||= y 等价于x = x || y,只是简写。它以扩展形式实现,与&&=+=-= 相同。

      大多数编程语言,包括 Ruby,都会在遇到的第一个 true 值上停止执行逻辑比较语句(如 ||)并返回该值。同样,当使用&& 时,它将在第一个 false 值处停止。

      一般来说:

      假 || foo()

      这将返回false,而不是评估foo()

      最好将模式描述为“惰性初始化器”,即变量仅定义一次,但仅在实际使用时才定义。这与“急切的初始化程序”形成对比,它会尽可能早地完成它,就像在 initialize 方法中一样。

      您会看到此模式的其他版本,例如:

      def arr
        @num ||= begin
          stuff = [ ]
          # ...
          stuff
        end
      end
      

      这可以处理初始值不那么微不足道并且可能需要一些工作才能产生的情况。再说一次,它只是在第一次调用该方法时才真正生成。

      Ruby 如何知道第二遍不再初始化它?很简单,到那时@num 已经被定义为某种东西了。

      请注意,如果您使用的值如 false 会被评估为非真,那么 ||= 每次都会触发。 Ruby 中仅有的两个逻辑错误值是 nilfalse,所以大多数时候这不是问题。

      如果您还需要处理 false,则必须以长格式方式执行此操作:

      def arr
        return @num unless num.nil?
      
        @num = false
      end
      

      有人说要添加一个类似于||= 的运算符,它只会在nil 上触发,但我认为这还没有添加到 Ruby 中。

      【讨论】:

        猜你喜欢
        • 2011-05-23
        • 2011-08-12
        • 2011-07-15
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        • 2013-08-14
        • 2011-04-28
        相关资源
        最近更新 更多