为什么这个 ruby​​ 使用 \u001 表示 1 以及如何更改?

Mic*_*ant 1 ruby fizzbuzz

我已经编写了经典的 fizzbuzz 代码。

规格:

describe "can determine fizzbuxx output for" do
  it "3" do
    expect(Fizzbuzz.nums(3)).to eq "123fizz"
  end 
end
Run Code Online (Sandbox Code Playgroud)

代码:

class Fizzbuzz
  def self.nums(n)
    result=""
    (1..n).each do |inner|
      puts "inner #{inner}"
      result << inner
      if (inner % 3)==0
        result << 'fizz'
      end
      if (inner % 5)==0
        result << 'buzz'
      end
    end
    result
  end
end
Run Code Online (Sandbox Code Playgroud)

为什么我得到\u001...而不是1

Failures:

1) can determine fizzbuxx output for 3
 Failure/Error: expect(Fizzbuzz.nums(3)).to eq "123fizz"

   expected: "123fizz"
        got: "\u0001\u0002\u0003fizz"

   (compared using ==)
 # ./fizzbuzz_spec.rb:5:in `block (2 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)

这是某种 utf-8 问题吗?

Sur*_*rya 5

在 Ruby 中,对于 string concatenation: <<,如果对象是 Integer,则将其视为代码点,并在连接之前转换为字符。从 Ruby 1.9 开始,默认编码是 UTF-8。代码点强制使用 UTF-8 编码:

1.chr(Encoding::UTF_8)
# => "\u0001"
Run Code Online (Sandbox Code Playgroud)

所以,当你这样做时:

"" << 1
Run Code Online (Sandbox Code Playgroud)

Ruby 实际上将其视为1一个代码点并尝试将其转换为 UTF-8 编码的字符串,并且实际上会这样做:

"" << 1.chr(Encoding::UTF_8)
#=> "\u0001"
Run Code Online (Sandbox Code Playgroud)

所以,来解决你的问题。您可以通过将代码更改为以下方式将 Fixnum 显式转换为 String:

result << inner.to_s
Run Code Online (Sandbox Code Playgroud)

或使用字符串插值:

result << "#{inner}"
Run Code Online (Sandbox Code Playgroud)