Rob*_*ion 2 string binary elixir
我决定在 Elixir 中构建自己的 CSV 解析器作为练习项目,并成功地让一些东西顺利运行。
\n\n我知道这个问题过去已经被一些“顶级”长生不老药开发者解决过,所以我决定看看他们是如何解决这个问题的。
\n\n我开始查看 elixir 模块NimbleCSV的源代码。它是由该语言的创建者 Jos\xc3\xa9 Valim 编写的,还有一些著名的 Elixir 开发人员的贡献,所以我认为这是一个不错的选择。
\n\n在parse_string函数中,他们使用函数检查字符串长度byte_size(string)。我想我明白这个功能是如何工作的。例如
iex()> byte_size(<<104, 101, 108, 108, 111>>)\n5\niex()> byte_size(<<104, 101, 108, 108, 111::9>>)\n6\nRun Code Online (Sandbox Code Playgroud)\n\n第一个函数是40 bitswhich is 5 bytes(如果没有另外说明,二进制中的每个值默认为 elixir 中的 8 位)
在第二个中,我将其中一个值指定为 ,9 bits因此总数为41 bits。这意味着它是6 bytes(由于四舍五入)
\n\n\n抱歉,如果某些语言不完全正确
\n
这对我来说很有意义。我的问题是,String.length在这种情况下他们为什么会选择这个功能?如果他们只是获取字符串的长度,不会返回相同的结果吗?
String.length/1返回字素的数量(每个字素可以是一个或多个字节),同时byte_size/1处理原始数据字节。
iex> byte_size "\xe2\x80\x8d\xe2\x80\x8d"\n18\niex> "\xe2\x80\x8d\xe2\x80\x8d" <> <<0>>\n<<240, 159, 145, 169, 226, 128, 141, 240, 159, 145, 169, 226, 128, 141, 240, 159, 145, 167, 0>>\n\niex> String.length "\xe2\x80\x8d\xe2\x80\x8d"\n1\n\niex> String.length "a"\n1\niex> byte_size "a"\n1\nRun Code Online (Sandbox Code Playgroud)\n来自文档:
\n\n\n字符串和二元运算
\n为了按照 Unicode 标准行事,该模块中的许多函数都以线性时间运行,因为它们需要考虑正确的 Unicode 代码点来遍历整个字符串。
\n例如,
\nString.length/1随着输入的增加,将需要更长的时间。另一方面,Kernel.byte_size/1总是以恒定的时间运行(即无论输入大小如何)。
不直接相关,但如果您想了解有关 Unicode 和 char 编码的更多信息,您可以阅读这篇文章并观看此视频
\n