list_to_binary和iolist_to_binary之间的区别是什么?

时间:2015-11-11 06:29:18

标签: erlang

我只知道erlang otp中的list_to_binary,但今天我看到了iolist_to_binary

我在erlang shell中尝试过,但我无法找到差异。

(ppb1_bs6@esekilvxen263)59> list_to_binary([<<1>>, [1]]).
<<1,1>>
(ppb1_bs6@esekilvxen263)60> iolist_to_binary([<<1>>, [1]]).
<<1,1>>
(ppb1_bs6@esekilvxen263)61> iolist_to_binary([<<1>>, [1], 1999]).
** exception error: bad argument
     in function  iolist_to_binary/1
        called as iolist_to_binary([<<1>>,[1],1999])
(ppb1_bs6@esekilvxen263)62> list_to_binary([<<1>>, [1], 1999]).  
** exception error: bad argument
     in function  list_to_binary/1
        called as list_to_binary([<<1>>,[1],1999])
(ppb1_bs6@esekilvxen263)63> list_to_binary([<<1>>, [1], <<1999>>]).
<<1,1,207>>
(ppb1_bs6@esekilvxen263)64> ioslist_to_binary([<<1>>, [1], <<1999>>]).
** exception error: undefined shell command ioslist_to_binary/1
(ppb1_bs6@esekilvxen263)65> iolist_to_binary([<<1>>, [1], <<1999>>]). 
<<1,1,207>>

从测试开始,我认为iolist_to_binary可能与list_to_binary相同。

3 个答案:

答案 0 :(得分:3)

在当前版本的Erlang / OTP中,两个函数都会自动展平你提供的列表或iolist(),只剩下一个区别,即list_to_binary / 1不接受二进制参数,但是iolist_to_binary / 1将: / p>

1> erlang:iolist_to_binary(<<1,2,3>>). 
<<1,2,3>>

2> erlang:list_to_binary(<<1,2,3>>).  
** exception error: bad argument
     in function  list_to_binary/1
        called as list_to_binary(<<1,2,3>>)

从iolist()的类型规范中可以清楚地看出:

maybe_improper_list(byte() | binary() | iolist(), binary() | [])

正如您所看到的,iolist()可以是二进制文件,但显然列表永远不能是二进制文件。

如果您想要跟进不正确的列表类型的卷积,您可以在(Erlang) Types and Function Specifications找到它的定义以及iolist()。

在实际使用方面,iolist()是一个混乱或不平整的列表。可以把它想象成一种懒惰的输出,故意不被作为优化的生产者列为正确的列表,因为不是每个消费者都需要压扁它。您可以通过检查io_lib的输出来查看它的外观:format / 2:

1> io_lib:format("Hello ~s ~b!~n", ["world", 834]).
    [72,101,108,108,111,32,"world",32,"834",33,"\n"]

或者:

2> io:format("~w~n", [  io_lib:format("Hello ~s ~b!~n", ["world", 834])  ]).
    [72,101,108,108,111,32,[119,111,114,108,100],32,[56,51,52],33,[10]]

我注意到你的许多例子都包含数字1999.尝试将任何包含任何大于255的数字的列表或iolist()转换为二进制文件总是会失败:

8> erlang:list_to_binary([1,2,3,255]).  
<<1,2,3,255>>
9> erlang:list_to_binary([1,2,3,256]).
** exception error: bad argument
     in function  list_to_binary/1
        called as list_to_binary([1,2,3,256])

这是因为它想要从列表中创建一个字节列表,并且高于255的数字在其可能的字节表示方面是不明确的;如果你的意思是小端或大端等,就不知道了(见(Wikipedia) Endianness)。

答案 1 :(得分:2)

差异不大。类型检查已完成。但最终由一个相同的功能引起。如果我正确找到了。

来源list_to_binary(https://github.com/erlang/otp/blob/maint/erts/emulator/beam/binary.c#L896):

BIF_RETTYPE list_to_binary_1(BIF_ALIST_1)
{
    return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_list_to_binary_1]);
}

来源iolist_to_binary(https://github.com/erlang/otp/blob/maint/erts/emulator/beam/binary.c#L903):

BIF_RETTYPE iolist_to_binary_1(BIF_ALIST_1)
{
    if (is_binary(BIF_ARG_1)) {
    BIF_RET(BIF_ARG_1);
    }
    return erts_list_to_binary_bif(BIF_P, BIF_ARG_1, bif_export[BIF_iolist_to_binary_1]);
}

答案 2 :(得分:0)

iolist_to_binary - 将iolist转换为二进制

你的参考: http://www.erlangpatterns.org/iolist.html http://www.erlang.org/doc/man/erlang.html