我真的不明白 Ru String
by 中 #encode
和 #force_encoding
之间的区别。 我知道"kam".force_encoding("UTF-8")
会强制"kam"
采用 UTF-8 编码,但#encode(encoding)
有何不同?
http://ruby-doc.org/core-2.0/String.html#method-i-encoding
差异很大。 force_encoding
设置给定的字符串编码,但不更改字符串本身,即 不会更改它在内存中的表示形式:
'łał'.bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII').bytes #=> [197, 130, 97, 197, 130]
'łał'.force_encoding('ASCII') #=> "xC5x82axC5x82"
encode
假定当前编码是正确的,并尝试更改字符串,使其在第二次编码中读取的方式相同:
'łał'.encode('UTF-16') #=> 'łał'
'łał'.encode('UTF-16').bytes #=> [254, 255, 1, 65, 0, 97, 1, 66]
简而言之,force_encoding
更改从字节读取字符串的方式,encode
更改写入字符串的方式而不更改输出(如果可能)
阅读此内容 更改编码
字符串的关联编码可以通过两种不同的方式更改。
首先,可以使用
String#force_encoding
将字符串的Encoding
设置为新的编码,而无需更改字符串的内部字节表示形式。这就是告诉 Ruby 字符串的正确编码的方法。
例:
string = "RxC3xA9sumxC3xA9"
string.encoding #=> #<Encoding:ISO-8859-1>
string.force_encoding(Encoding::UTF_8) #=> "Ru00E9sumu00E9"
其次,可以对字符串进行转码,即将其内部字节表示形式转换为另一种编码。其关联的编码也设置为其他编码。有关各种形式的转码,请参阅
String#encode
,有关对转码过程的其他控制,请参阅 Encoding::Converter 类。
例:
string = "Ru00E9sumu00E9"
string.encoding #=> #<Encoding:UTF-8>
string = string.encode!(Encoding::ISO_8859_1)
#=> "RxE9sumxE9"
string.encoding
#=> #<Encoding::ISO-8859-1>
的类比
- force_encoding ==> 用不同的语言说同样的话
- 编码 ==> 用不同的语言解释相同的声音
哪里
- 字节 ==> 件事
- 编码 ==> 语言
- 字符串输出 ==> 声音
根据这篇博文:In Ruby, strings are a combination of an array of bytes, and an encoding object
(*)。
x = 'Hello World' ---> <Encoding:UTF-8>
调用 force_encoding 会改变原始字符串,其中编码会创建具有不同编码的新字符串。
force_encoding
# before force_encoding
x = 'Hello World' ---> <Encoding:UTF-8>
x.force_encoding "US-ASCII"
# after force_encoding
x ---> <Encoding:US-ASCII>
编码
# before encode
x = 'Hello World' ---> <Encoding:UTF-8>
y = x.encode("US-ASCII")
# after encode
x ---> <Encoding:UTF-8>
y ---> <Encoding:US-ASCII>
另一篇很棒的博客文章(阅读"解决方案"部分),解释了设计Ruby String <Bytes + Encoding>
的原因(*)。