我编写了一个有效的函数,将二进制文件拆分为每个字符,但我觉得有一种更简单的方法:
my_binary_to_list(<<H,T/binary>>) ->
%slightly modified version of http://erlang.org/doc/efficiency_guide/binaryhandling.html
[list_to_binary([H])|my_binary_to_list(T)];
my_binary_to_list(<<>>) -> [].
> my_binary_to_list(<<"ABC">>).
[<<"A">>,<<"B">>,<<"C">>]
我认为这可能因为list_to_binary([H])
而导致凌乱,因为H
应该已经是二进制文件。
我尝试直接使用该链接功能但获得了"AA"
这不是我想要的。然后我尝试了[H]
并获得了["A","B","C"]
这也不是我想要的。
答案 0 :(得分:8)
您可以从单个字节创建二进制文件,而无需创建列表并像这样调用list_to_binary
:
my_binary_to_list(<<H,T/binary>>) ->
[<<H>>|my_binary_to_list(T)];
您也可以在这里使用二元理解来在一行中执行与上述相同的逻辑:
1> [<<X>> || <<X>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]
你也可以直接提取大小为1的二进制文件(虽然这可能不比上面快):
2> [X || <<X:1/binary>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]
编辑:使用timer:tc/1
的快速工作台在大约一半的时间内运行第二个代码,但是出于性能原因,您应该在使用任何一个代码之前对自己进行基准测试。也许第二个是通过创建子二进制文件来共享大二进制文件?
1> Bin = binary:copy(<<"?">>, 1000000).
<<"????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"...>>
2> timer:tc(fun() -> [<<X>> || <<X>> <= Bin] end).
{14345634,
[<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
3> timer:tc(fun() -> [X || <<X:1/binary>> <= Bin] end).
{7374003,
[<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
答案 1 :(得分:3)
您可以将列表推导与位字符串生成器一起使用(<=
使用二进制文件,而不是消耗列表的<-
):
> [<<A>> || <<A>> <= <<"foo">>].
[<<"f">>,<<"o">>,<<"o">>]
在您的版本中,list_to_binary([H])
可以替换为<<H>>
- 两者都生成包含一个字节的二进制文件。是否使用列表推导而不是递归函数符合&#34;更容易&#34;可能是品味问题。