2015-10-08 51 views
1

我想知道爲什麼a在下面是a[:a]後空哈希被稱爲,這是不是空:使用嵌套哈希和哈希爲默認值沒有按預期工作

a = Hash.new({a:1}) # => {} 
a[:a][:a] += 1  # => 2 
a     # => {} 
a[:a]    # => {:a=>2} 

我知道{a: 1}在每個不存在的密鑰之間共享(a[:something_inexistent])。但爲什麼它不顯示爲a的關鍵?如果可能的話,使用Ruby的內部將非常感激。

+1

'{a:1}'是默認的*值*,所以如果'a'沒有鍵'k','a [k]'返回'{a:1}'但它不會改變散列。如果你想改變哈希,'a [:k] = a [:k]; a#=> {:k => {:a => 1}}'。對於一個數值爲散列的變量,'h'會比'a'更好,就像數組'a'會比'h'好。 –

+0

我最近看了一篇文章,可能會有所幫助:[Bottomless Ruby Hash](http://firedev.com/posts/2015/bottomless-ruby-hash/) – ShallmentMo

回答

4

這是因爲a[:a]從來沒有分配。當您執行a[:a]時,它不會返回存儲的值,而是返回默認值。

與此不同,當你不是有:

a = Hash.new{|h, k| h[k] = {a: 1}} 

然後,每當缺少鍵被調用時,該塊被執行,其值分配給鍵,a將不再是一個空哈希。

+0

爲什麼傳遞'{a:1}到'Hash.new'設置默認值爲1,但?這似乎有點奇怪。 –

+0

我認爲他的一部分混亂是'a = Hash.new({a:1})'不同於'a = {a:1}'。我知道,當我第一次看到它的時候就知道了。 – Beartech

+0

啊,我想我現在從看[API](http://docs.ruby-lang.org/en/2.2.0/Hash.html#method-c-new)就能理解了。看看他們是如何傳遞「Go Fish」作爲參數的,然後調用'h [「c」]'並返回「Go Fish」?當密鑰不存在時,他設置默認值爲另一個內部哈希{{a:1}'。當他執行'+ = 1'命令時,他實際上正在改變默認值,現在是'{a:2}',但從未將其分配給任何鍵,因此主散列仍爲空。 –