iolist跟list有什么区别?
April 6th, 2010
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: iolist跟list有什么区别?
看到erlang-china.org上有个帖子在问这个问题
一直不太明白iolist,跟list到底有什么区别?请各位大侠指教。。
我翻看了半天erlang的文档也没写的太明白,所以就看看源码:
erts/emulator/beam/utils.c
3015int io_list_len(Eterm obj) 3016{ 3017 Eterm* objp; 3018 Sint len = 0; 3019 DECLARE_ESTACK(s); 3020 goto L_again; 3021 3022 while (!ESTACK_ISEMPTY(s)) { 3023 obj = ESTACK_POP(s); 3024 L_again: 3025 if (is_list(obj)) { 3026 L_iter_list: 3027 objp = list_val(obj); 3028 /* Head */ 3029 obj = CAR(objp); 3030 if (is_byte(obj)) { 3031 len++; 3032 } else if (is_binary(obj) && binary_bitsize(obj) == 0) { 3033 len += binary_size(obj); 3034 } else if (is_list(obj)) { 3035 ESTACK_PUSH(s, CDR(objp)); 3036 goto L_iter_list; /* on head */ 3037 } else if (is_not_nil(obj)) { 3038 goto L_type_error; 3039 } 3040 /* Tail */ 3041 obj = CDR(objp); 3042 if (is_list(obj)) 3043 goto L_iter_list; /* on tail */ 3044 else if (is_binary(obj) && binary_bitsize(obj) == 0) { 3045 len += binary_size(obj); 3046 } else if (is_not_nil(obj)) { 3047 goto L_type_error; 3048 } 3049 } else if (is_binary(obj) && binary_bitsize(obj) == 0) { /* Tail was binary */ 3050 len += binary_size(obj); 3051 } else if (is_not_nil(obj)) { 3052 goto L_type_error; 3053 } 3054 } 3055 3056 DESTROY_ESTACK(s); 3057 return len; 3058 3059 L_type_error: 3060 DESTROY_ESTACK(s); 3061 return -1; 3062}
从源码可以看出来iolist是这样的定义的:
1. []
2. binary
3. 列表, 每个元素是int(0-255)或者binary或者iolist.
其中binary是指 bitsize % 8 == 0 .
int 是0-255
root@ubuntu:/usr/src/otp# erl Erlang R13B04 (erts-5.7.5) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.7.5 (abort with ^G) 2> iolist_size(<<>>). 0 3> iolist_size(<<1:1>>). ** exception error: bad argument in function iolist_size/1 called as iolist_size(<<1:1>>) 4> iolist_size(<<1:8>>). 1 5> iolist_size([]). 0 6> iolist_size(<<1,2>>). 2 7> iolist_size([1,2]). 2 8> iolist_size([1,2, <<1,2>>]). 4 9> iolist_size([1,2, <<1,2>>, [2]]). 5 10> iolist_size([1,2, <<1,2>>, [2]]). 5 11> iolist_size([<<1:1>>]). ** exception error: bad argument in function iolist_size/1 called as iolist_size([<<1:1>>]) 12> iolist_size([257]). ** exception error: bad argument in function iolist_size/1 called as iolist_size([257])
Iolist的作用是用于往port送数据的时候.由于底层的系统调用如writev支持向量写, 就避免了无谓的iolist_to_binary这样的扁平话操作, 避免了内存拷贝,极大的提高了效率.
建议多用.
Post Footer automatically generated by wp-posturl plugin for wordpress.
Erlang Reference Manual
Types and Function Specifications:
iolist() :: maybe_improper_list( char() | binary() | iolist(), binary() | [])
所以呢,这些是iolist:
[“hello” | <>]
[“hello” | []]
[“hello” | “world”]
iolist_to_binary参数是IoListOrBinary
第一个是 : [ “hello” | < > ]
别再转换俺的 哦…嘿嘿
[“hello” | 《”world”》] 这样行了吧
["hello"]= [$h, $e, $l, $l, $o].
所以还是[], 元素是int
以前经常犯错误, 使用 iolist_to_binary.