我最近开始使用 Ruby 进行编码,对某些行为感到困惑。
我正在使用 2.2.3p173 并显示以下内容:
__ENCODING__ #=> #<Encoding:UTF-8> Default encoding in 2.2.3
"my_string".encoding #=> #<Encoding:UTF-8>
Object.to_s.encoding #=> #<Encoding:US-ASCII>
Object.new.to_s.encoding #=> #<Encoding:ASCII-8BIT>
这种编码差异的原因是什么?
最佳答案
不错的发现!
简短的回答是它完全是任意的,它取决于 Ruby 如何在内部构建返回的字符串。
有一大堆内部 C 函数可以使用 US-ASCII 编码构造空字符串或文字字符串:rb_usascii_str_new
和类似的。它们经常用于通过附加较小的字符串片段来构造字符串。几乎每个 to_s
方法都这样做:
[].to_s.encoding
#<Encoding:US-ASCII>
{}.to_s.encoding
#<Encoding:US-ASCII>
$/.to_s.encoding
#<Encoding:US-ASCII>
1.to_s.encoding
#<Encoding:US-ASCII>
true.to_s.encoding
#<Encoding:US-ASCII>
Object.to_s.encoding
#<Encoding:US-ASCII>
那么为什么不Object.new.to_s
呢?这里的关键是 Object#to_s
是 every 类的回退 to_s
方法,所以为了使其通用但信息丰富,他们对其进行编码以输出对象内部指针的值。最简单的方法是使用 sprintf
和 %p
说明符。 但是 编码 Ruby 的 sprintf
包装器 rb_sprintf
的人变得懒惰,只是将编码设置为 NULL
回落到 ASCII-8BIT
。所以通常任何返回格式化字符串的东西都会有这样的编码:
Object.new.to_s
#<Encoding:ASCII-8BIT>
nil.sort rescue $!.to_s.encoding
#<Encoding:ASCII-8BIT>
[].each.to_s.encoding
#<Encoding:ASCII-8BIT>
对于脚本定义的字符串,它们会像您期望的那样获得默认编码 UTF-8。
关于ruby - Ruby 中的字符串编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33704416/