提问人:LancerRevolutionX 提问时间:2/6/2021 更新时间:2/6/2021 访问量:190
为什么 Ruby Integer 方法 'chr' 默认使用 ASCII-8 位,而不是 UTF-8?
Why does Ruby Integer method 'chr' use ASCII-8bit, not UTF-8 by default?
问:
根据它的源代码 https://www.rubydoc.info/stdlib/core/Integer:chr,如果没有提供参数,此方法使用 ASCII 编码,实际上,当使用参数和不参数调用时,它会给出不同的结果:
irb(main):002:0* 255.chr
=> "\xFF"
irb(main):003:0' 255.chr 'utf-8'
=> "ÿ"
为什么会这样?Ruby 不是应该在任何地方默认使用 UTF-8 吗?至少所有字符串似乎都用 UTF-8 编码:
irb(main):005:0> "".encoding
=> #<Encoding:UTF-8>
答:
为什么会这样?
对于从 U+0000 到 U+007F (127) 的字符,绝大多数单八位字节和可变长度字符编码都同意编码。特别是,他们都同意是 ASCII 的严格超集。
换言之:对于包括 U+007F、ASCII 在内的字符,整个 ISO8859 系列、整个 DOS 代码页系列、整个 Windows 系列以及 UTF-8 实际上是相同的。因此,对于 U+0000 和 U+007F 之间的字符,ASCII 是合乎逻辑的选择:
0.chr.encoding
#=> #<Encoding:US-ASCII>
127.chr.encoding
#=> #<Encoding:US-ASCII>
但是,对于高于 127 的任何内容,或多或少没有两个字符编码一致。事实上,127 以上的绝大多数字符甚至不存在于绝大多数字符集中,因此在绝大多数字符编码中没有编码。
换句话说:几乎不可能为 127 以上的字符找到单一的默认编码。
因此,Ruby 选择的编码是 ,它基本上是一种伪编码,意思是“这实际上不是文本,这是非结构化的未知二进制数据”。(对于歇斯底里的葡萄干,这种编码也别名为 ,我觉得这绝对可怕,因为 ASCII 是 7 位,句点,任何使用第 8 位的东西根据定义都不是 ASCII。Encoding::BINARY
ASCII-8BIT
128.chr.encoding
#=> #<Encoding:ASCII-8BIT>
255.chr.encoding
#=> #<Encoding:ASCII-8BIT>
另请注意,Integer#chr
仅限于单个八位字节,即范围为 0 到 255,因此这里实际上不需要多八位字节或可变长度编码。
Ruby 不是应该在任何地方默认使用 UTF-8 吗?
你说的是哪种编码?Ruby 大约有六个。
对于绝大多数编码,您的陈述是不正确的。
- 区域设置编码是环境的默认编码
- 文件系统编码是用于文件路径的编码:该值由文件系统确定
- 对象的外部编码是假定读取的文本和写入的文本的编码:默认值为区域设置编码
IO
- 对象的内部编码是写入对象的 S 必须采用的编码,从对象读取的 S 必须转码为:默认值为默认内部编码,其默认值为 ,表示不会发生转码
IO
String
IO
String
IO
nil
- 脚本编码是读取 Ruby 脚本的编码,脚本中的文字也将继承这种编码:它在脚本的开头设置了一个魔术注释,默认值为 UTF-8
String
所以,正如你所看到的,有许多不同的编码,许多不同的默认值,其中只有一个是 UTF-8。这些编码实际上都与您的问题无关,因为既不是文字也不是对象。它是由该方法使用它认为合适的任何编码创建的对象。128.chr
String
IO
String
Integer#chr
评论
irb(main):002:0> 1050.chr 'utf-8' => "К"
评论