当前位置 : 主页 > 编程语言 > ruby >

ruby中的哈希数据类型中的“默认值是同一个对象”

来源:互联网 收集:自由互联 发布时间:2021-06-23
参见英文答案 Strange, unexpected behavior (disappearing/changing values) when using Hash default value, e.g. Hash.new([])4个 我是Ruby新手并且运行Ruby Koans.在Ruby Koans的about_hashes.rb文件中,有一个为散列分配默认
参见英文答案 > Strange, unexpected behavior (disappearing/changing values) when using Hash default value, e.g. Hash.new([])                                    4个
我是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”}.

网友评论