Erlang數據類型的表示和實現(1)——數據類型回顧


本文介紹 Erlang 語言中使用的各種數據類型以及這些數據類型在 Erlang 虛擬機內部的表示和實現。了解數據類型的實現可以幫助大家在實際開發過程中正確選擇數據類型,並且可以更好更高效地操作這些數據類型。本文對 Erlang 數據類型及實現的總結目前是最全面的,可以作為 Erlang 數據結構的參考手冊。盡管我寫的內容都試圖在各種參考資料和 Erlang 虛擬機源代碼中驗證,但是難免會有理解錯誤或各種低級錯誤,希望大家指正,也希望能對 Erlang 愛好者們有幫助。

Erlang數據類型回顧

Erlang 從語言的層面上說是一門比較簡單的語言,因此語言原生的數據結構也比較簡單。下面簡單回顧一下 Erlang 語言支持的數據結構:

  • 整數:小整數和大整數。Erlang 可以表達任意大小的整數,只要不超過內存容量。如果一個整數可以用一個機器字[注1]表示,那么這個整數在內部通過“小整數”表示(這里是粗略的描述,實際不到一個機器字);否則,自動升級為“大整數”表示。在用戶層面感知不到內部的具體表示,只要用就行了。示例:1,-1,123,473804731289473815748315139。
  • 浮點數:標准的 IEEE 754-1985 格式的浮點數。例如 3.14,1.234E-10,-0.5。
  • atom(原子):小寫字母開頭的不帶引號的字符串,是一種字面常量,可以用來表達任何想表達的意義。也可以用單引號引起來,這樣用起來更靈活,比如第一個字母可以大寫,中間還可以插入空格。示例:abc,node@myhost.com,error,ok,'Hello World'。
  • 布爾值:實際上內部就是原子 true 和原子 false 表示的,但是有一些 BIF(例如 is_boolean)和操作符(例如 and 和 or 等)用於支持布爾操作的語義。
  • tuple(元組):組合數據結構,相當於固定大小的數組,每一個元素可以是任意類型。示例: {error, badarg},{person, "Siyao", 1985}。
  • list(列表):看上去和元組一樣,也是組合數據結構,每一個元素可以是任意類型,可以包含任意個元素,由於 Erlang 變量都是 immutable 的,所以列表的大小也是不可變的,但是列表的內部表示和支持的操作和元組完全不同。示例:[monday, tuesday],[{person, "Alice"}, {person, "Bob"}]。
  • 字符串:實際上就是字符的列表,而字符實際上和整數沒有區別。字符串就是一種采用大家熟知的字符串表示語法表示字符列表的語法糖。示例:"Hello World"。注意字符串用的是雙引號,而原子用的是單引號。
  • fun(匿名函數):fun 是體現 Erlang 作為函數式語言的一個重要特性。fun 是“匿名”函數,可以在程序中動態生成,可以當做數據傳入其他函數或從函數返回。因此 fun 類型的數據也是 Erlang 中的一種數據結構。示例:fun(X) -> 2*X end。
  • binary:用於表示一堆原始的無類型的字節數據。由於 binary 是整塊的數據,所以非常適合各種數據傳輸和處理的場合。binary 可以方便地和 Erlang 中其他數據結構互相轉換,因此相當於可以在語言層面非常方便地執行數據結構的 marshalling 和 unmarshalling 操作。在 binary 中還可以打破字節的邊界進行任意位匹配操作,因此可以非常方便地從各種二進制數據(例如網絡數據包和二進制文件等)中提取字段。
  • ref:通過 BIF 調用 make_ref() 生成的一個幾乎唯一的值,因為在同一 Erlang 節點上,連續調用 \(2^{82}\) 次 make_ref() 得到的值都是不一樣的。ref 是透明的數據類型,只能拿來用,但不能對其操作。ref 數據可以放在消息里發送至其他 Erlang 節點,Erlang 的分布式機制會自動加上節點相關的信息,使得 ref 在整個集群內保持幾乎唯一。也可以看出,ref 有兩種表示形式,一種是 local 表示形式,還有一種是 external 形式。local 版本就是在本地的表示形式,但是發送到其他節點之后,其他節點得到的 ref 數據就是通過 external 形式表示的。
  • pid:Erlang 進程 id。類似 ref,也是透明的,也區分 local 和 external。
  • port:表示 port id,同樣也是透明的,並區分 local 和 external。

以上完整地概述了 Erlang 語言中采用的數據類型。下面我們就來看這些數據類型在 Erlang 虛擬機內部都是怎么表達和實現的。了解這些原理性的內容我們就可以更加高效地使用這些數據結構。


[注1] 這里說的機器字(后面都簡稱“字”)指的是機器原生指針寬度的數據結構。比如在 64 位機器上,機器字長度為 8 個字節。要注意這里所說的機器字和 Intel 文檔中的“習俗”不同。Intel 文檔中因為歷史原因,一直將一個字定義為 16 位,即 2 字節,所以 64 位寬的數據結構在 Intel 的文檔中都表示為 quad word(因此在對應的匯編指令中也會添加 q 后綴)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM