我正在阅读Ruby编程,实用程序员指南(Pick Axe),并且作者声称它们之间有区别:
var = var || "Default Value"
和
var || = "Default Value"
我不明白这一点,因为与我所看到的没有区别。任何人都可以帮我这个吗?
答案 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