红宝石中的 #encode 和 #force_encoding 有什么区别



我真的不明白 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>的原因(*)。

最新更新