【问题标题】:Non destructive force_encoding?非破坏性 force_encoding?
【发布时间】:2013-06-10 12:47:45
【问题描述】:

方法force_encoding 中是否有不修改调用者对象的版本?

所以,当前的 force_encoding 是这样工作的:

> a
 => "Ü" 
> a.force_encoding("BINARY")
 => "\xC3\x9C" 
> a
 => "\xC3\x9C" 

我希望结果是这样的:

> a
 => "Ü" 
> a.force_encoding_non_destructive("BINARY")
 => "\xC3\x9C" 
> a
 => "Ü" 

请注意,我完全理解 a.force_encoding("UTF-16LE").force_encoding("UTF-8") 产生相同的结果(当然,假设 a 以前是 UTF-8)并且字符串中的字节没有被修改。但是,字符串状态被修改,因此这种方法是破坏性的。例如:

a="a"
a.freeze
a.force_encoding("BINARY")
# raises error

【问题讨论】:

  • 我认为您误解了 force_encoding 在您的示例中的实际作用。它不会以任何方式修改字符串的内容。相反,它正在更改字符串的一个属性——控制它如何呈现给您的属性。
  • @Denis 我相信你错了。在您的控制台中尝试此操作:a = "a" ; b = "b" ; a + b。然后,试试这个:a = "a" ; b = "b" ; a + b ; a.force_encoding("UTF-16LE"); a + b。如果同一语句在调用其中一个对象中的方法后生成不同的输出,则表明该方法修改了对象状态。
  • 保持。更改为 UTF-16LT 与更改为二进制(您在示例中使用)不同。 :-) 二进制就是……字节流。 UTF-8 和 UTF-16 对相同的字符进行不同的编码,并相应地修改字符串(如果可能)。相比之下,据我所知,将字符串强制为二进制会产生完全相同的字符串。
  • 是的,对象的编码属性已经改变。但不是字符串本身,当您切换到二进制编码并返回时。

标签: ruby encoding


【解决方案1】:

force_encoding 在不改变接收器字节方面是非破坏性的。它只是改变了字节的解释方式,即它改变了字符串的 characters:

a = "Ü"
a.bytes.to_a               #=> [195, 156]
a.chars.to_a               #=> ["Ü"]

a.force_encoding("BINARY")
a.bytes.to_a               #=> [195, 156]
a.chars.to_a               #=> ["\xC3", "\x9C"]

编码存储在字符串实例中。要获取“二进制”编码的副本,请使用:

a.dup.force_encoding("BINARY")

【讨论】:

  • 那么如何解释这个:a="a"; a.freeze; a.force_encoding("BINARY")?我将编辑我的问题以涵盖这一点,因为你不是第一个告诉这个的人。
  • 我说“不改变接收者的字节”。字符串的编码确实发生了变化。我已经更新了我的答案。
  • a="Ü"; b="Ü"; a.force_encoding("BINARY"); a.bytes.to_a == b.bytes.to_a => true
  • 在上面的答案中阅读我的评论 - 我建议您使用 dup 添加一个简单的方法实现......因为这就是问题所要问的:-)
【解决方案2】:

对于另一个简短的回答,我深表歉意。显然,#force_encoding 修改了字符串属性,但我不会说它是破坏性的。您可以随时撤消更改。如果你想吃蛋糕,请#dup it。

【讨论】:

  • 实际上,这次答案的内容比 cmets 或简单的谷歌搜索中已经告诉的要多,因为这有效:a.freeze.dup.force_encoding("BINARY"),因此对象在复制时会失去冻结。如果没有标准方法可以做到这一点,那么最好的方法就是复制它。
【解决方案3】:

另一种解决方案:

a = "Ü"
b = ::String.new a, :encoding => "binary"

比起dup,我更喜欢它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2011-07-07
    • 2021-01-31
    • 2016-03-06
    • 1970-01-01
    相关资源
    最近更新 更多