2016-01-12 156 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

相關問題