我最近开始使用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>
Run Code Online (Sandbox Code Playgroud)
这种编码差异的原因是什么?
不错的发现!
简短的回答是它完全是任意的,它取决于 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>
Run Code Online (Sandbox Code Playgroud)
那么为什么不Object.new.to_s呢?这里的关键是每个类Object#to_s的回退to_s方法,因此为了使其具有通用性但信息丰富,他们将其编码为输出对象内部指针的值。最简单的方法是使用和 说明符。但是,任何编写 Ruby包装器的人都变得懒惰,只是将编码设置为回退到. 因此,通常返回格式化字符串的任何内容都将具有以下编码:sprintf%psprintfrb_sprintfNULLASCII-8BIT
Object.new.to_s
#<Encoding:ASCII-8BIT>
nil.sort rescue $!.to_s.encoding
#<Encoding:ASCII-8BIT>
[].each.to_s.encoding
#<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)
至于由脚本定义的字符串,如您所料,它们将获得默认编码 UTF-8。