Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 为什么在冻结哈希本身之前冻结哈希值?_Ruby_Performance - Fatal编程技术网

Ruby 为什么在冻结哈希本身之前冻结哈希值?

Ruby 为什么在冻结哈希本身之前冻结哈希值?,ruby,performance,Ruby,Performance,我注意到有些人做了{'foo':'bar'.freeze}.freeze,而不仅仅是{'foo':'bar'}.freeze 更好吗?如果是,原因是什么?hash.freeze冻结哈希本身,但不冻结其值。这意味着您将无法再分配新值或删除键,但仍可以更改现有值: hash = {a: 'hello'}.freeze hash[:b] = 'there' #=> exception! hash[:a] = 'hello there' #=> exception! hash[:a].upc

我注意到有些人做了
{'foo':'bar'.freeze}.freeze
,而不仅仅是
{'foo':'bar'}.freeze


更好吗?如果是,原因是什么?

hash.freeze
冻结哈希本身,但不冻结其值。这意味着您将无法再分配新值或删除键,但仍可以更改现有值:

hash = {a: 'hello'}.freeze
hash[:b] = 'there' #=> exception!
hash[:a] = 'hello there' #=> exception!
hash[:a].upcase! #=> no exception
hash #=> {a: 'HELLO'}
在第三行中,我们尝试为现有密钥分配一个新字符串,但失败了。但是在第四行中,我们直接修改字符串的实例。散列只是保留对其他对象的引用,所以修改字符串根本不会影响散列

如果同时冻结字符串,则情况会有所不同:

hash = {a: 'hello'.freeze}.freeze
hash[:a].upcase! #=> exception!

默认情况下,Ruby字符串是可变的。因此,第一种方法阻止某人使用冻结字符串和冻结哈希不是一回事。关于@engineersmnky的评论,假设
h={:a=>'cat'}。冻结
。然后,
h.object#id#=>1820
h[:a].object#id#=>1840
。无法更改哈希,因为它已冻结:
h[:a]='dog'#=>FrozenError:无法修改冻结的哈希:{:a=>“cat”}
。但是,我们可以使用另一个字符串
h[:a]
:替换('dog')#=>“dog”。注意
h#=>{:a=>'dog'}
h.object#id#=>1820
h[:a]。object#id#=>1840
…现在也冻结
:a
的值:
h[:a]。冻结#=>“dog”
。然后
h[:a]。替换('pig')#=>冻结错误:无法修改冻结字符串:“dog”