这是错误的,因为编码不同:
[128].pack("C").encoding
#=> #<Encoding:ASCII-8BIT>
"\x80".encoding
#=> #<Encoding:UTF-8>
(使用ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
)
在 ruby 2.0 中,字符串的默认编码是 UTF-8,但以某种方式pack
返回一个 ASCII 8 位编码的字符串。
那为什么是 [127].pack('C') == "\x79"
真的呢?
但是,[127].pack('C') == "\x79"
是true
,因为对于 ASCII 和 UTF-8 的码点来说0
没有127
区别。ruby 的字符串比较考虑了这一点(查看rubinius 源代码):
def ==(other)
[...]
return false unless @num_bytes == other.bytesize
return false unless Encoding.compatible?(self, other)
return @data.compare_bytes(other.__data__, @num_bytes, other.bytesize) == 0
end
mri c-source类似,但更难理解。
我们观察到,比较会检查兼容的编码。让我们试试:
Encoding.compatible?([127].pack("C"), "\x79") #=> #<Encoding:ASCII-8BIT>
Encoding.compatible?([128].pack("C"), "\x80") #=> nil
我们看到,从代码点 128 开始,false
即使两个字符串由相同的字节组成,比较也会返回。