Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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何时使用方法!vs重新赋值_Ruby - Fatal编程技术网

Ruby何时使用方法!vs重新赋值

Ruby何时使用方法!vs重新赋值,ruby,Ruby,在使用Ruby时,我经常发现自己在使用方法和之间存在冲突或使用普通方法将值赋回。我不知道什么时候用什么。 例如 我有两个散列(h1和h2),我想合并它们并将值存储回散列h1,现在我应该使用吗 h1.merge!(h2) 或 h1=h1.合并(h2) 这两者有什么区别吗 这两者有什么区别吗 是的,当然有 你应该使用(bang)版本,当您要更改接收器本身时 示例 h1 = {a: 1} h2 = {b: 2} h3 = h1.merge(h2) # => {:a=>1, :b=>2

在使用Ruby时,我经常发现自己在使用方法和
之间存在冲突或使用普通方法将值赋回。我不知道什么时候用什么。
例如
我有两个散列(h1和h2),我想合并它们并将值存储回散列h1,现在我应该使用吗
h1.merge!(h2)
h1=h1.合并(h2)

这两者有什么区别吗

这两者有什么区别吗

是的,当然有

你应该使用
(bang)版本,当您要更改接收器本身时

示例

h1 = {a: 1}
h2 = {b: 2}
h3 = h1.merge(h2) # => {:a=>1, :b=>2}
h1 # => {:a=>1}
现在请看:

h1 = {a: 1}
h2 = {b: 2}
h1.merge!(h2) # => {:a=>1, :b=>2}
h1 # => {:a=>1, :b=>2}
h1=h1。合并(h2)给出了相同的答案

嗯,这是因为,在应用
hash#merge
方法之后,您正在将新哈希分配到
h1

h1 = {a: 1}
h2 = {b: 2}
h1.object_id # => 69435570
h1 = h1.merge(h2) # => {:a=>1, :b=>2}
h1 # => {:a=>1, :b=>2}
h1.object_id # => 69434820

正如您所说,我希望合并它们并将值存储回散列h1,那么我建议使用。因为
h1=h1.merge(h2)
h1.merge相同!(h2)
(将保存新的哈希创建,并将其分配回
h1
)。

大多数情况下
h1.merge之间的差异非常小!(h2)
h1=h1。合并(h2)

但是,请注意:

自从<代码>合并修改旧的散列,则可能会无意中影响程序中包含对该散列的引用的其他对象。修改作为方法参数接收的哈希是一种不好的做法,因为调用方通常不期望它

使用
合并
不是函数式编程,如果你喜欢的话

使用
合并
可能更有效,因为它不会创建新的散列,特别是对于大型散列

我大部分时间都会使用
merge
,而只使用
merge如果我确定它是安全和更好的

在使用Ruby时,我经常发现自己在使用 方法有一个!或者使用正常的方法

你应该考虑更重要的事情,所以只要遵循规则:我永远不会使用bang方法。现在自由翱翔

require 'benchmark'

n = 1_000_000

h1 = {a: 1, b: 2}
h2 = {b: 3, c: 4}

Benchmark.bm(20) do |b|
  b.report("no-bang-hash-merge") do
    n.times { h1 = h1.merge h2 }
  end

  b.report("bang-hash-merge") do
    n.times { h1.merge! h2 }
  end
end

--output:--
                          user     system      total        real
no-bang-hash-merge     2.750000   0.050000   2.800000 (  2.817345)
bang-hash-merge        0.400000   0.000000   0.400000 (  0.406870)


因此,如果你需要速度,砰的一声离开。否则,不要冒险。

h1=h1。合并(h2)给出了相同的答案。在大多数情况下,我宁愿避免副作用(有时用
表示)。我发现减少副作用(在任何语言中)通常会使代码更容易推理,并有助于避免一些微妙的意外交互。我发现字符串的副作用(
gsub!
etc)尤其难以处理,部分原因是许多常见的“现代”语言没有Ruby这样的可变字符串。(当然有很多非
方法也会产生副作用..而且Ruby无论如何都不会试图做到“纯粹”)+1用于比给定用例更大规模的思考。不要违背其他程序员的期望,这一点很重要。像这样的测试没有多大意义,因为散列的大小和重叠键的数量可能会改变结果。我现在正在运行一些额外的测试,我将发布结果。当然,我正在等待看到这些结果:)
require 'benchmark'

hash_size = 10_000

#Keys overlap:
key1 = 'a'
key2 = nil

h1 = {}
hash_size.times do |i|
  h1[key1] = i
  key2 = key1.dup if i == hash_size/2
  key1.succ!
end


h2 = {}
hash_size.times do |i|
  h2[key2] = i
  key2.succ!
end

=begin
#No overlap:
key = 'a'

h1 = {}
hash_size.times do |i|
  h1[key] = i
  key.succ!
end


h2 = {}
hash_size.times do |i|
  h2[key] = i
  key.succ!
end
=end

n = 100_000

puts "50% of keys overlap, hash size #{hash_size}:"
Benchmark.bm(20) do |b|
  b.report("no-bang-hash-merge") do
    n.times { h1 = h1.merge h2 }
  end

  b.report("bang-hash-merge") do
    n.times { h1.merge! h2 }
  end
end

--some test runs:---

50% of keys overlap, hash size 10000:
                           user     system      total        real
no-bang-hash-merge   1500.570000  74.520000 1575.090000 (1695.523240)
bang-hash-merge      255.910000   0.940000 256.850000 (269.957178)



No keys overlap, hash size 10000:
                           user     system      total        real
no-bang-hash-merge   1906.070000 109.340000 2015.410000 (2151.865636)
bang-hash-merge      162.680000   0.190000 162.870000 (163.369607)