a = a ||之间的差异b和a || = b

时间:2016-01-12 05:19:27

标签: ruby

我正在阅读Ruby编程,实用程序员指南(Pick Axe),并且作者声称它们之间有区别:

var = var || "Default Value"

var || = "Default Value"

我不明白这一点,因为与我所看到的没有区别。任何人都可以帮我这个吗?

2 个答案:

答案 0 :(得分:3)

引用资源here

  

在a = a ||中b,每次运行时语句都设置为a,   而使用|| a = b,a仅在a逻辑上为假时才设置(即   如果它是零或假,因为||是短路'。也就是说,如果   ||的左侧比较是真的,没有必要   检查右侧。

这基本上意味着他们的行为与你的开发人员类似,但在内部实施方式与上述不同。

修改 正如评论中指出的,上述说明考虑了a || a = b而不是a ||= b。一个非常好的观点,并阅读相同的链接进一步阐明了这一点:

  

如果未定义a,则为|| a = 42引发NameError,而a || = 42   因此,他们似乎不是等同的表达。

所以,再次,它们不是同一个语句,因为Ruby在分析时看到一个赋值时就会分配一个变量(a ||= 42就是这种情况)。

最后一句话,所以你不要以为我是这样做的,:))

  

Ruby在解析阶段看到赋值并创建变量   以某种方式,它不会与|| a = 42,即使它结束了   一旦实际执行发生,就像后者一样。

答案 1 :(得分:3)

如果你使用带有getter和setter的类,差异会变得更明显:

class Foo
  def var
    puts 'Foo#var called'
    @var
  end
  def var=(value)
    puts 'Foo#var= called'
    @var = value
  end
end

您的第一个示例导致Foo#var=被称为时间:

f = Foo.new
f.var = f.var || "Default Value"
# Foo#var called
# Foo#var= called
f.var = f.var || "Default Value"
# Foo#var called
# Foo#var= called

在第二个示例中,Foo#var=仅被调用一次:

f = Foo.new
f.var ||= "Default Value"
# Foo#var called
# Foo#var= called
f.var ||= "Default Value"
# Foo#var called