I only know list_to_binary
in erlang otp, but today I see iolist_to_binary
?
I tried it in erlang shell, but I can't find the difference.
(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>>
From the test, I think iolist_to_binary
may be the same as list_to_binary
.
In current versions of Erlang/OTP both functions will automatically flatten the list or iolist() you provide, leaving functionally only one difference, which is that list_to_binary/1 will not accept a binary parameter, but iolist_to_binary/1 will:
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>>)
This is clear from the type specification of iolist():
maybe_improper_list(byte() | binary() | iolist(), binary() | [])
As you can see, iolist() can be a binary, but clearly a list can never be a binary.
If you want to follow through the convolution of the improper list type you can find its definition, along with iolist() at (Erlang) Types and Function Specifications.
In terms of practical use iolist() is a messy or unflattened list. Think of it as a kind of lazy output, deliberately not flattened to be a proper list by the produver as an optimisation because not every consumer will need to flatten it. You can see what it looks like by checking the output of 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"]
Or:
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]]
I notice that many of your examples include the number 1999. Attempts to convert any list or iolist() which contain any number that is greater than 255 to a binary will always fail by the way:
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])
This is because it wants to create a list of bytes from your list, and a number above 255 is ambiguous in terms of its possible byte representation; it can't be known if you mean little endian or big endian, etc (see (Wikipedia) Endianness).
The differences are not large. Type checking is done. But in the end caused by one and the same function. If I correctly found.
Source 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]);
}
Source 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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With