我是Ruby新手并且运行Ruby Koans.在Ruby Koans的about_hashes.rb文件中,有一个为散列分配默认值的示例.
hash = Hash.new([]) hash[:one] << "uno" hash[:two] << "dos" puts hash[:one] # this is ["uno", "dos"]
哈希[:one]& hash [:two]或任何键如hash [:three](非现有键)都具有值[“uno”和“dos”]我不明白“<<”在这里使用.此外,当我尝试提取键和&哈希值,或打印键/值,它是空的.
puts (hash.values.size) # size is 0 here puts (hash.keys.size) # size is 0 puts hash.values # nothing gets printed puts hash.keys #nothing gets printed.
那么这里发生了什么?存储的值在哪里,如果它们没有作为键或值存储在散列中.
在下一个例子中,当Hash被定义为
hash = Hash.new {|hash, key| hash[key] = [] } hash[:one] << "uno" hash[:two] << "dos" puts hash[:one] #this is "uno" puts hash[:two] #this is "dos" puts hash[:three] # this is undefined.
我想在第二个例子中,hash正在使用空白数组初始化所有键.因此当“<<”时,“uno”会被附加到空数组中使用此运算符?我对这两个例子感到困惑.我不知道他们俩发生了什么.我也无法在谷歌中找到关于这个例子的更多信息.如果有人可以帮我解释这两个例子,那将会很有帮助.提前致谢
hash = Hash.new([])此语句创建一个空哈希,其默认值为空数组.如果散列没有密钥k,则hash [k]返回默认值[].这很重要:只返回默认值不会修改哈希值.
当你写:
hash[:one] << "uno" #=> ["uno"]
在hash有一个键之前:一,hash [:one]被默认值替换,所以我们有:
[] << "uno" #=> ["uno"]
这解释了为什么散列没有改变:
hash #=> {}
现在写:
hash[:two] << "dos" #=> ["uno", "dos"] hash #=> {}
为了了解为什么我们得到这个结果,让我们重写上面的内容如下:
hash = Hash.new([]) #=> {} hash.default #=> [] hash.default.object_id #=> 70209931469620 a = (hash[:one] << "uno") #=> ["uno"] a.object_id #=> 70209931469620 hash.default #=> ["uno"] b = (hash[:two] << "dos") #=> ["uno", "dos"] b.object_id #=> 70209931469620 hash.default #=> ["uno", "dos"]
因此,您可以看到object_id为70209931469620的默认数组是附加“uno”和“dos”的单个数组.
如果我们写了:
hash[:one] = hash[:one] << "uno" #=> hash[:one] = [] << "uno" => ["uno"] hash #=> { :one=>"uno" }
我们得到了我们希望的东西,但不是那么快:
hash[:two] = hash[:two] << "dos" #=> ["uno", "dos"] hash #=> {:one=>["uno", "dos"], :two=>["uno", "dos"]}
这仍然不是我们想要的,因为两个键的值都是相同的数组.
hash = Hash.new {| hash,key | hash [key] = []}
当哈希没有密钥时,此语句会导致执行块.这确实通过添加键值pair1来更改哈希值.
所以现在:
hash[:one] << "uno"
导致阻止:
{ |h,k| h[k] = [] }
做出任务:
hash[:one] = []
之后:
hash[:one] << "uno"
将“uno”附加到一个空数组,该数组是键的值:one,我们可以验证:
hash #=> { :one=>"uno" }
这与写作效果相同:
hash[:one] = (hash[:one] || []) << "uno"
(当没有默认值时,(hash [:one] || = [])<<“uno”的扩展版本. 同样的,
hash[:two] << "dos" #=> ["dos"] hash #=> {:one=>["uno"], :two=>["dos"]}
这通常是我们想要的结果.
1但是,块不需要更改哈希值.该块可以包含任何代码,例如,{puts“Have a nice day”}.