为什么String.to_atom将编码选项硬编码为:utf8?
https://github.com/elixir-lang/elixir/blob/d6bb3342b7ea8b921b3d4b69f65064c4158c99d7/lib/elixir/lib/string.ex#L1927
def to_atom(string) do
:erlang.binary_to_atom(string, :utf8)
end
erlang binary_to_atom
的可用编码选项是:
latin1 | unicode | utf8
http://erlang.org/documentation/doc-8.0-rc1/erts-8.0/doc/html/erlang.html#binary_to_atom-2
答案 0 :(得分:4)
<强> TL; DR 强>
因为Erlang宇宙最终在所有地方都使用UTF-8。
<强>讨论强>
latin1
正在消失,并且主要是UTF-8的一个子集(少数字符除外),unicode
是utf8
的旧别名,只留下一个普遍适用的选项:utf8
。这很重要,因为UTF-8原子(和弦)是Erlang内部以及Elixir内部的前进方式。
如果您使用非UTF-8编码处理旧数据,请在致电binary_to_atom/2
之前将其转换为。
这也符合Erlang标准库中较新的string
和unicode
模块更改 - 它们最终可以作为普遍接受的标准在UTF-8上解决经过几十年的不确定性(因为编码很难并且当Erlang被发明时对此没有太多的一致意见)。
关于编码练习的一句话
我在日本工作主要处理业务数据,其中一些很老,而且其中一些是非常疯狂的编码。我倾向于在Erlang中编写代码(我更喜欢小语言)。当一些较旧的字符串处理函数和unicode模块被写入时,字符串分为两类:
时代变了。现在我们知道字符串几乎总是以UTF-8形式出现,并且Unixverse中的所有内容最终都确定了这一点,这已经产生了令人愉快的效果,即(几乎)所有其他有意义的系统也会在此基础上解决(如果不是内部的话) ,然后通过强大的检测库,可以在UTF-16和UTF-8之间进行选择。
你实际做的情况下有非UTF-8数据然后你知道这是的情况,并且应该在将数据发送到通用函数之前将其转换例如binary_to_atom/2
。我实际上认为我们应该转向包括binary_to_atom/1
并从Erlang R20完全逐步淘汰binary_to_atom/2
- which is what has already happened with list_to_atom/1
(是的!)。
那么这对您的代码有何影响?
当您开始处理古代编码时,代码的复杂性会突然爆炸,并且需要立即包含它,以免它以精神错乱的方式感染整个代码库。实现这一目标的最佳方法是在业务系统之外保持疯狂,并在边缘进行转换。每当我们处理疯狂编码中出现的旧数据我们已经知道并为此做好准备 - 所以我们在前面明确地转换为UTF-8,所以以后没有什么可以遇到的更深入的系统。
您可能会想,“他们为什么不检测每个字符串的编码?”唉,没有正确的方法来检测字符串编码。高度自信是不可能的。在大多数情况下,它也很快成为一项过时的任务,因为今天生成的绝大多数数据都是UTF-8(或UTF-16,但很难通过网络遇到这种情况)。