首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >list_to_binary和iolist_to_binary有什么不同?

list_to_binary和iolist_to_binary有什么不同?
EN

Stack Overflow用户
提问于 2015-11-11 14:29:18
回答 3查看 3.3K关注 0票数 5

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

我在erlang shell中尝试过,但我找不到区别。

代码语言:javascript
复制
(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相同。

EN

回答 3

Stack Overflow用户

发布于 2015-11-11 17:52:23

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

代码语言:javascript
复制
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()的类型规范可以清楚地看出这一点:

代码语言:javascript
复制
maybe_improper_list(byte() | binary() | iolist(), binary() | [])

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

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

就实际使用而言,iolist()是一个杂乱的或未展开的列表。把它想象成一种懒惰的输出,故意不把它扁平化成一个适当的列表,因为并不是每个消费者都需要扁平化它。您可以通过检查io_lib:format/2的输出来查看它的样子:

代码语言:javascript
复制
1> io_lib:format("Hello ~s ~b!~n", ["world", 834]).
    [72,101,108,108,111,32,"world",32,"834",33,"\n"]

或者:

代码语言:javascript
复制
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的任何数字的任何list或iolist()转换为二进制总是会失败:

代码语言:javascript
复制
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)。

票数 5
EN

Stack Overflow用户

发布于 2015-11-11 15:09:29

差异并不大。类型检查已完成。但最终都是由同一个函数引起的。如果我没记错的话。

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

代码语言:javascript
复制
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):

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-11-11 14:34:03

iolist_to_binary -将iolist转换为二进制

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33645336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档