为什么使用concat运算符

时间:2018-09-21 19:39:29

标签: ruby

我是红宝石的新手,但是我很确定这些东西是等效的。但是我正在为一个重要的脚本提供一个机会,只是想确定一下。

这就是他们现在拥有的:

def generate_names options
  names = []

  name = options.name
  sen = options.sen
  ari = options.ari

  options.targets.each do |target|
    names << "#{name}" + " Test " + "#{target}"
  end

  names
end

这是我要更改为的内容,请注意,在names <<行中,我删除了+。这是完全一样的吗?我什至对平等进行了测试,但只想确保这一点。

def generate_names options
  names = []

  name = options.name
  sen = options.sen
  ari = options.ari

  options.targets.each do |target|
    names << "#{name} Test #{target}"
  end

  names
end

此外,我在irb中尝试了此操作,但出现错误:

"#{name}" + " Test " + "#{target}".eql?("#{name} Test #{target}") ? "equal" : "not"

给出的错误是:

TypeError: no implicit conversion of false into String
    from (irb):20:in `+'
    from (irb):20
    from /usr/bin/irb:12:in `<main>'

1 个答案:

答案 0 :(得分:2)

单独查看:

names << "#{name}" + " Test " + "#{target}"

这确实是不规则的代码。如果这是一个字符串值,"#{name}"将等效于name,因此引号是多余的,更糟糕​​的是,创建另一个立即被丢弃的字符串。这一行仅创建四个字符串。

另一个更好:

names << "#{name} Test #{target}"

这将创建一个字符串并将其插入。插值几乎总是比连接更好,因为它产生的垃圾更少。

您的irb测试存在缺陷:

"#{name}" + " Test " + "#{target}".eql?("#{name} Test #{target}") ? "equal" : "not"

这首先在 just .eql?上评估target部分,这显然不匹配,因此其评估结果为:

("#{name}" + " Test " + false) ? "equal" : "not"

由于无法将false和字符串组合在一起,这将失败。

测试此方法的方法是强制执行特定的评估顺序:

("#{name}" + " Test " + "#{target}").eql?("#{name} Test #{target}") ? "equal" : "not"