檢視原始碼 Erlang 函式庫
Elixir 提供與 Erlang 函式庫絕佳的互操作性。事實上,Elixir 不鼓勵只包覆 Erlang 函式庫,而是直接與 Erlang 程式碼介接。在此部分,我們將介紹一些 Elixir 中找不到的最常見且有用的 Erlang 功能。
Erlang 模組的命名慣例與 Elixir 不同,且以小寫字母開頭。在兩種情況下,模組名稱都是原子,我們透過傳送至模組名稱來呼叫函式
iex> is_atom(String)
true
iex> String.first("hello")
"h"
iex> is_atom(:binary)
true
iex> :binary.first("hello")
104
隨著您對 Elixir 愈來愈熟練,您可能想更詳細地探索 Erlang STDLIB 參考手冊。
二進位模組
內建的 Elixir 字串模組處理以 UTF-8 編碼的二進位。 :binary
模組 在處理不一定是 UTF-8 編碼的二進位資料時很有用。
iex> String.to_charlist("Ø")
[216]
iex> :binary.bin_to_list("Ø")
[195, 152]
以上的範例顯示了差異; 字串
模組傳回 Unicode 碼點,而 :binary
處理原始資料位元組。
格式化文字輸出
Elixir 不包含類似於 C 和其他語言中找到的 printf
函式。幸運的是,可以利用 Erlang 標準函式庫函式 :io.format/2
和 :io_lib.format/2
。第一個格式化為終端機輸出,而第二個格式化為 iolist。格式化指定符與 printf
不同,請參閱 Erlang 文件以取得詳細資訊。
iex> :io.format("Pi is approximately given by:~10.3f~n", [:math.pi])
Pi is approximately given by: 3.142
:ok
iex> to_string(:io_lib.format("Pi is approximately given by:~10.3f~n", [:math.pi]))
"Pi is approximately given by: 3.142\n"
加密模組
:crypto
模組 包含雜湊函式、數位簽章、加密等
iex> Base.encode16(:crypto.hash(:sha256, "Elixir"))
"3315715A7A3AD57428298676C5AE465DADA38D951BDFAC9348A8A31E9C7401CB"
:crypto
模組是隨 Erlang 附帶的 :crypto
應用程式的一部分。這表示您必須在專案組態中將 :crypto
應用程式列為額外的應用程式。為執行此操作,請編輯您的 mix.exs
檔案以包含
def application do
[extra_applications: [:crypto]]
end
任何不屬於 :kernel
或 :stdlib
Erlang 應用程式的模組都必須在 mix.exs
中明確列出其應用程式。您可以在 Erlang 文件中找到任何 Erlang 模組的應用程式名稱,位於側邊欄 Erlang 標誌下方。
有向圖模組
:digraph
和 :digraph_utils
模組包含用於處理由頂點和邊緣建立的有向圖的函數。在建構圖形後,其中的演算法將有助於找出例如兩個頂點之間的最短路徑或圖形中的迴圈。
給定三個頂點,找出從第一個到最後一個的最短路徑。
iex> digraph = :digraph.new()
iex> coords = [{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}]
iex> [v0, v1, v2] = (for c <- coords, do: :digraph.add_vertex(digraph, c))
iex> :digraph.add_edge(digraph, v0, v1)
iex> :digraph.add_edge(digraph, v1, v2)
iex> :digraph.get_short_path(digraph, v0, v2)
[{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}]
請注意,:digraph
中的函數會就地更改圖形結構,這是可能的,因為它們是實作為 ETS 表格,如下所述。
Erlang 項儲存
:ets
和 :dets
模組分別處理大型資料結構在記憶體或磁碟中的儲存。
ETS 讓您可以建立包含元組的表格。預設情況下,ETS 表格受到保護,這表示只有擁有者程序可以寫入表格,但任何其他程序都可以讀取。ETS 有一些功能,允許將表格用作簡單的資料庫、鍵值儲存或快取機制。
ets
模組中的函數會修改表格狀態作為副作用。
iex> table = :ets.new(:ets_test, [])
# Store as tuples with {name, population}
iex> :ets.insert(table, {"China", 1_374_000_000})
iex> :ets.insert(table, {"India", 1_284_000_000})
iex> :ets.insert(table, {"USA", 322_000_000})
iex> :ets.i(table)
<1 > {<<"India">>,1284000000}
<2 > {<<"USA">>,322000000}
<3 > {<<"China">>,1374000000}
數學模組
:math
模組包含涵蓋三角函數、指數和對數函數的常見數學運算。
iex> angle_45_deg = :math.pi() * 45.0 / 180.0
iex> :math.sin(angle_45_deg)
0.7071067811865475
iex> :math.exp(55.0)
7.694785265142018e23
iex> :math.log(7.694785265142018e23)
55.0
佇列模組
:queue
模組提供有效實作(雙端)FIFO(先進先出)佇列的資料結構
iex> q = :queue.new
iex> q = :queue.in("A", q)
iex> q = :queue.in("B", q)
iex> {value, q} = :queue.out(q)
iex> value
{:value, "A"}
iex> {value, q} = :queue.out(q)
iex> value
{:value, "B"}
iex> {value, q} = :queue.out(q)
iex> value
:empty
rand 模組
:rand
有函數用於傳回隨機值和設定隨機種子。
iex> :rand.uniform()
0.8175669086010815
iex> _ = :rand.seed(:exs1024, {123, 123534, 345345})
iex> :rand.uniform()
0.5820506340260994
iex> :rand.uniform(6)
6
zip 和 zlib 模組
:zip
模組讓您可以從磁碟或記憶體讀取和寫入 ZIP 檔案,以及擷取檔案資訊。
此程式碼計算 ZIP 檔案中的檔案數量
iex> :zip.foldl(fn _, _, _, acc -> acc + 1 end, 0, :binary.bin_to_list("file.zip"))
{:ok, 633}
:zlib
模組處理 zlib 格式的資料壓縮,就像 Unix 系統中的 gzip
命令列工具。
iex> song = "
...> Mary had a little lamb,
...> His fleece was white as snow,
...> And everywhere that Mary went,
...> The lamb was sure to go."
iex> compressed = :zlib.compress(song)
iex> byte_size(song)
110
iex> byte_size(compressed)
99
iex> :zlib.uncompress(compressed)
"\nMary had a little lamb,\nHis fleece was white as snow,\nAnd everywhere that Mary went,\nThe lamb was sure to go."
學習 Erlang
如果你想深入了解 Erlang,這裡有一系列線上資源,涵蓋 Erlang 的基礎知識和進階功能
這份 Erlang 語法:速成課程 簡潔地介紹 Erlang 的語法。每個程式碼片段都附有 Elixir 中的等效程式碼。這是一個機會,不僅讓你接觸 Erlang 的語法,還能複習你對 Elixir 所學的知識。
為大善學習 Erlang! 是 Erlang、其設計原則、標準函式庫、最佳實務等等的絕佳入門指南。讀完上面提到的速成課程後,你就可以跳過書中前幾章,因為它們主要在講解語法。當你讀到 《銀河便車指南:並行程式設計》 章節時,真正的樂趣才要開始。
最後一步驟是查看你可能會在除錯時使用的現有 Elixir(和 Erlang)函式庫。