为什么要“替换”而不是将新对象分配给同一个变量?

Why would you `replace` rather than assign a new object to the same variable?

我在查看 Solitaire Cipher 中的测验摘要时偶然发现了这段代码:

def triple_cut
  a = @deck.index( 'A' )
  b = @deck.index( 'B' )
  a, b = b, a if a > b
  @deck.replace( [ @deck[(b + 1)..-1],
                   @deck[a..b],
                   @deck[0...a] ].flatten )
end

我不明白为什么有一个单独的方法 replace。为什么不只执行以下操作?

@deck = @deck[(b + 1)..-1] +
        @deck[a..b] +
        @deck[0...a]

当您可以将它们加在一起时,为什么还要麻烦地应用两个单独的方法(replaceflatten)?我没有 运行 遇到任何问题。

  1. 它通过不 re-creating 数组来节省内存。
  2. 您可以在没有 re-assigning 变量的情况下引用同一个对象。

当 replacing/re-assigning 大数组时,Array#replace 似乎比赋值 = 表现更好。


require 'benchmark'

n = 500
ary_size = 10000

replacement = ['b']*ary_size*3

Benchmark.bm do |x|
  x.report { n.times { arr = ['a']*ary_size; arr.replace(replacement)} }
  x.report { n.times { arr = ['a']*ary_size; arr = replacement}}
end

输出:

       user     system      total        real
   0.000000   0.000000   0.000000 (  0.002253)
   0.015000   0.000000   0.015000 (  0.015224)
[Finished in 0.1s]

ruby的美妙之处在于,在很多情况下,做事没有正确的方法。对于您的情况,我认为您的解决方案既有效又更易于阅读。

至于 replace,它的工作原理是将值复制到不同的现有数组中,然后将其分配给不同的对象。

例如

x = [1, 2]
y = [3]
x.replace(y) # x is [3] and y is [3]
x << 5 # x is [3, 5] and y is [3]

x = [1, 2]
y = [3]
x = y # x is now pointing to the same object as y
x << 5 # both x and y are [3, 5] because they are the same object