一个区别是,因为<< 可以正常工作,所以它比+= 快一些。以下代码
require 'benchmark'
a = ''
b= ''
puts Benchmark.measure {
100000.times { a << 'test' }
}
puts Benchmark.measure {
100000.times { b += 'test' }
}
产量
0.000000 0.000000 0.000000 ( 0.004653)
0.060000 0.060000 0.120000 ( 0.108534)
更新
我最初误解了这个问题。这是发生了什么。 Ruby 变量只存储对对象的引用,而不是对象本身。这是与您执行相同操作的简化代码,并且具有相同的问题。我已经告诉它在循环的每次迭代中打印temp 和words_array。
def helper(word)
words_array = []
word.length.times do |i|
temp = ''
(i...word.length).each do |j|
temp << word[j]
puts "temp:\t#{temp}"
words_array << temp unless words_array.include?(temp)
puts "words:\t#{words_array}"
end
end
words_array
end
p helper("cat")
这是打印的内容:
temp: c
words: ["c"]
temp: ca
words: ["ca"]
temp: cat
words: ["cat"]
temp: a
words: ["cat", "a"]
temp: at
words: ["cat", "at"]
temp: t
words: ["cat", "at", "t"]
["cat", "at", "t"]
如您所见,在第一次之后的内部循环的每次迭代中,ruby 只是简单地替换了words_array 的最后一个元素。这是因为words_array 持有对temp 所引用的字符串对象的引用,而<< 会修改该对象而不是创建一个新对象。
在外循环的每次迭代中,temp 被设置为一个新对象,并且该新对象被附加到 words_array,因此它不会替换之前的元素。
+= 构造在内部循环的每次迭代中都会向 temp 返回一个新对象,这就是它的行为符合预期的原因。