在erlang資料型別的c原始碼解析(1)-eterm講到,當eterm的低2位為01b時,就是list型別,剩餘的位數表示乙個指向列表的指標。
另外就是,先講結論,有助於理解,erlang中的list在c的層面上是乙個鍊錶。
// cons用於構建乙個鍊錶節點
#define cons(hp, car, cdr) \
(car(hp)=(car), cdr(hp)=(cdr), make_list(hp))
// cad:取出鍊錶結點的資料部分
#define car(x) ((x)[0])
// cdr:取出鍊錶結點的next指標
#define cdr(x) ((x)[1])
// make_list最後會呼叫到_unchecked_make_list(x), 向eterm打上list的標籤,實質上是置eterm的低2位為10b
// compress_pointer為壓縮,與下面的expand_pointer對應
#define _unchecked_make_list(x) ((uint) compress_pointer(x) + tag_primary_list)
// list_val最後會呼叫到_unchecked_list_val(x), 將低2位的標籤去掉,再取對應位址的值
#define _unchecked_list_val(x) ((eterm*) expand_pointer((x) - tag_primary_list))
(這些蛋疼的命名**於lisp語言,有興趣可以查一下)
bif_rettype length_1
(bif_alist_1)
list = bif_arg_1;
// i為返回值,代表鍊錶長度
i =0;
// 迴圈取next,next不為空的話i自增,直到nil
while
(is_list
(list))if
(is_not_nil
(list)
)bif_ret
(make_small
(i))
;}
從這個函式和上述cons的定義,都可以得出list在c層面上是乙個鍊錶。
bif_rettype tuple_to_list_1
(bif_alist_1)
// 這裡相當於取得tuple的指標
tupleptr =
tuple_val
(bif_arg_1)
;// n為tuple的長度
n =arityval
(*tupleptr)
;// 將tuple看成乙個陣列,tupleptr[n]就是c語言層面的陣列
// 在程序堆上分配空間,由於乙個鍊錶節點要儲存資料和next指標,所以申請的空間大小為tuple長度的2倍
hp =
halloc
(bif_p,
2* n)
; tupleptr++
;// 從陣列的最後乙個元素開始迴圈
while
(n--
)bif_ret
(list)
;}
github上otp17**的erl_term.h和erl_bif_lists.c erlang的強資料型別
在mailist中,一位朋友表示疑問,為什麼下面的語句提示出錯?erlang的執行時資料繫結有什麼特殊規則?file open test.file write,raw,提示badarg,引數錯誤。其實不是執行時繫結有什麼問題,而是math pow 2返回的資料型別為float,而file open ...
erlang的資料型別 (2)
繼續前面說列表。列表裡面的元素,第乙個成為head,head之後的都叫tail。用erlang的內建方法看一下 hd 1,2,3,4 1 tl 1,2,3,4 2,3,4 為什麼要這樣呢?因為列表的指標是在頭部的,對頭部進行操作是最快捷和高效的。使用豎線 能快速區分頭部和尾部 h t 1,2,3,4...
21 erlang資料型別
erlang資料型別可以分為以下7大類 1 數值number 包括整形,浮點型,還有 char 進製表示法base value.2 元組term 由 包含的各種資料結構,統稱元組 3 列表 和字串 term1,termn 當然字串也屬於列表的以一種,a a 97 ab a,b 97,98 注意字串的...