2016-01-12 158 views
4

我读通过编程红宝石,语用程序员指南(该锄书),作者声称,有之间的差异:a = a ||之间的区别b和a || = B

var = var || "Default Value" 

和:

var || = "Default Value" 

我不明白这一点,因为与我所看到的没有什么不同。谁能帮我这个?

+1

据我所知,这两个表达式对于'var'的任何值都有相同的结果?您能否在书中添加一段引文来提问您的问题,以表明作者的含义? :-) – Drenmi

+0

我认为它只是写出同样表达的两种方式。 – Atri

+0

你们很酷。谢谢 – gates

回答

3

引述资源here

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

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

编辑: 正如在评论中指出,上面的解释认为a || a = b而不是a ||= b。非常好的一点,并阅读相同的链接进一步阐明了这一点:

如果a没有定义, a = 42引发NameError,而|| = 42 返回42.因此,它们似乎不是等效表达式。

因此,它们又不是同一个语句,因为Ruby在分析时看到赋值的那一刻就分配了一个变量(这是a ||= 42的情况)。

最后一个报价,所以你不要以为我在做这件事,:)

红宝石看到在分析阶段的任务,并在某种程度上创建变量 表示不会与一个|| a = 42,即使它结束了 的行为就像后者一旦发生实际执行。

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 

而在你的第二个

+2

这是OP所指的吗?这个问题指出'a = a ||之间的区别b'和'a || = b',而不是'a = a || b'和'a || a = b'? – Drenmi

+1

@Drenmi:'a || = b'是'a ||的快捷方式。 a = b'。 (如果'a'不是'nil'或'false'_,则省略赋值__) – potashin

+0

是的,即使我没有得到|| = b也是|| a = b,你能解释一下吗? @potashin – gates

3

如果你使用一类具有getter和setter的差别变得更加明显例如,Foo#var=仅被称为一次:

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

为什么'Foo.var'在第二种情况下不会被第二次调用? –

+1

@WandMaker'|| ='仅在左侧值为“nil”或“false”时进行赋值。 'f.var'最初是'nil',所以第一个'f.var || ='赋值''默认值''。第二次,'f.var'返回''默认值'',所以不执行任务。 – Stefan

+1

如果我没有弄错,等价的表达式就像'f.var.tap {| v | f.var = v || '默认值'除非v}' – Stefan

相关问题