我正在寻找一种在Ruby中连接字符串的更优雅的方式。

我有如下一行:

source = "#{ROOT_DIR}/" << project << "/App.config"

有更好的方法吗?

那么<<和+之间有什么区别呢?


当前回答

你也可以这样使用%:

source = "#{ROOT_DIR}/%s/App.config" % project

这种方法也适用于'(单)引号。

其他回答

木偶:

$username = 'lala'
notify { "Hello ${username.capitalize}":
    withpath => false,
}

因为这是一个路径,我可能会使用数组和join:

source = [ROOT_DIR, project, 'App.config'] * '/'

+操作符是正常的连接选择,并且可能是连接字符串的最快方式。

+和<<之间的区别在于<<改变了对象的左侧,而+则不会。

irb(main):001:0> s = 'a'
=> "a"
irb(main):002:0> s + 'b'
=> "ab"
irb(main):003:0> s
=> "a"
irb(main):004:0> s << 'b'
=> "ab"
irb(main):005:0> s
=> "ab"

下面是受这个要点启发的另一个基准测试。它比较动态和预定义字符串的连接(+)、追加(<<)和插值(#{})。

require 'benchmark'

# we will need the CAPTION and FORMAT constants:
include Benchmark

count = 100_000


puts "Dynamic strings"

Benchmark.benchmark(CAPTION, 7, FORMAT) do |bm|
  bm.report("concat") { count.times { 11.to_s +  '/' +  12.to_s } }
  bm.report("append") { count.times { 11.to_s << '/' << 12.to_s } }
  bm.report("interp") { count.times { "#{11}/#{12}" } }
end


puts "\nPredefined strings"

s11 = "11"
s12 = "12"
Benchmark.benchmark(CAPTION, 7, FORMAT) do |bm|
  bm.report("concat") { count.times { s11 +  '/' +  s12 } }
  bm.report("append") { count.times { s11 << '/' << s12 } }
  bm.report("interp") { count.times { "#{s11}/#{s12}"   } }
end

输出:

Dynamic strings
              user     system      total        real
concat    0.050000   0.000000   0.050000 (  0.047770)
append    0.040000   0.000000   0.040000 (  0.042724)
interp    0.050000   0.000000   0.050000 (  0.051736)

Predefined strings
              user     system      total        real
concat    0.030000   0.000000   0.030000 (  0.024888)
append    0.020000   0.000000   0.020000 (  0.023373)
interp    3.160000   0.160000   3.320000 (  3.311253)

结论:MRI内插重。

让我给你们看看我的经验。

我有一个返回32k记录的查询,对于每个记录,我调用一个方法将该数据库记录格式化为一个格式化的字符串,然后将其连接到一个字符串,在所有这个过程结束时将转换为磁盘上的文件。

我的问题是,在24k左右,连接字符串的过程开始变得痛苦。

我用的是常规的“+”运算符。

当我换到'<<'时,就像变魔术一样。真的很快。

所以,我记得我的旧时光-大约1998年-当我使用Java和连接字符串使用'+',从字符串改为StringBuffer(现在我们,Java开发人员有StringBuilder)。

我相信在Ruby世界中+ / <<的过程和+ / StringBuilder是一样的。在Java世界中追加。

第一个在内存中重新分配整个对象,另一个只是指向一个新地址。