对 ruby 中的“||= OR EQUALS”运算符的疑问[重复]

问题描述 投票:0回答:2

我对 ruby 中的 OR EQUALS (

||=
) 运算符有一些疑问。 ruby解释器是如何实现的呢?这是代码示例:

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

在这种情况下,当我们使用 OR EQUALS 运算符时,第一次调用此方法会初始化变量并添加一个元素,这很好。当第二次调用

arr
时,它如何知道数组中有一个元素..

ruby operators equals
2个回答
3
投票

在 Ruby 中,有两个值被视为逻辑假。第一个是布尔值

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


0
投票

一般来说,

x ||= y
相当于
x = x || y
,只是简写而已。它以扩展形式实现,与
&&=
+=
-=
相同。

大多数编程语言(包括 Ruby)都会在遇到第一个

true
值时停止执行逻辑比较语句(如 ||)并返回该值。同样,当使用 && 时,它将在第一个
false
值处停止。

一般而言:

假 || foo()

这将返回

false
并且不评估
foo()

该模式最好被描述为“惰性初始化程序”,即变量仅定义一次,但仅在实际使用时定义。这与“热切初始化程序”形成鲜明对比,后者会尽早执行此操作,就像在

initialize
方法中一样。

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

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

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

Ruby 如何知道在第二遍时不要再次初始化它?很简单,到那时

@num
已经被定义为某个东西了。

请注意,如果您使用像

false
这样的值,这些值将被评估为非 true,那么
||=
每次都会触发。 Ruby 中唯一的两个逻辑错误值是
nil
false
,所以大多数时候这不是问题。

如果您还需要处理

false
,则必须以长格式执行此操作:

def arr
  return @num unless num.nil?

  @num = false
end

有人讨论添加一个类似

||=
的运算符,该运算符只会在
nil
上触发,但我认为这还没有添加到 Ruby 中。

© www.soinside.com 2019 - 2024. All rights reserved.