Erlang 什么';列表到二进制和iolist到二进制之间的区别是什么?

Erlang 什么';列表到二进制和iolist到二进制之间的区别是什么?,erlang,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]]).

我只知道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>>
(ppb1_bs6@esekilvxen263)59>列出\u到\u二进制([,[1]])。
(ppb1_bs6@esekilvxen263)60>iolist_到_二进制([,[1]])。
(ppb1_bs6@esekilvxen263)61>iolist_to_binary([,[1],1999])。
**异常错误:参数错误
函数中的iolist_到_二进制/1
称为iolist_to_binary([,[1],1999])
(ppb1_bs6@esekilvxen263)62>列出二进制文件([,[1],1999])。
**异常错误:参数错误
在函数列表中\u到\u二进制/1
称为列表到二进制([,[1],1999])
(ppb1_bs6@esekilvxen263)63>列出二进制文件([,[1],])。
(ppb1_bs6@esekilvxen263)64>ioslist_到_二进制([,[1],])。
**异常错误:未定义的shell命令ioslist\u to\u binary/1
(ppb1_bs6@esekilvxen263)65>iolist_到_二进制([,[1],])。

从测试中,我认为
iolist\u to\u binary
可能与
list\u to\u binary
iolist\u to\u binary
-将iolist转换为二进制

供参考:
差别不大。类型检查已完成。但最终还是由同一个功能引起的。如果我找对了

源列表\u到\u二进制文件():

源iolist_到_二进制文件():


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

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()可以是二进制的,但很明显,列表永远不能是二进制的

如果您想了解不正确列表类型的卷积,可以在中找到它的定义以及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"]
或:

我注意到你们的许多例子包括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])
8>erlang:list_to_binary([1,2,3255])。
9> erlang:list_to_binary([1,2,3256])。
**异常错误:参数错误
在函数列表中\u到\u二进制/1
称为列表\u到\u二进制([1,2,3256])

这是因为它想从您的列表中创建一个字节列表,而255以上的数字在其可能的字节表示方面是不明确的;不知道您指的是little endian还是big endian等(请参阅)。

您可以通过在Github上添加指向源文件的链接来改进此答案,以供将来参考。有人想知道为什么iolist_to_binary/1是BIF;同样的代码也可以用纯Erlang编写。
maybe_improper_list(byte() | binary() | iolist(), binary() | [])
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]]
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])