在 Elixir 裡,如果想從可列舉的資料結構(例如陣列或範圍)中隨機挑選一個元素,我們會使用 Enum.random。這個函式會挑出單一元素,而且每個元素被挑中的機率都相同。
Elixir 本身沒有挑選隨機浮點數的函式。要做到這件事,我們必須直接使用 Erlang。
Elixir 程式碼執行在 BEAM 虛擬機上。BEAM 是 Erlang 執行階段系統的一部分。由於受到 Erlang 啟發,又共用它的執行環境,Elixir 與 Erlang 函式庫之間有著絕佳的互通性。這表示 Elixir 開發者可以在自己的 Elixir 程式碼裡使用 Erlang 函式庫。事實上,在 Elixir 社群中,若某個功能已由 Erlang 函式庫提供,並不鼓勵再為它寫一套 Elixir 函式庫。
因此,某些功能(例如數學運算或計時器函式)在 Elixir 中只能透過 Erlang 取得。
Erlang 的標準函式庫可以直接在我們的 Elixir 程式碼中使用,不需要任何額外步驟。
Erlang 函式的呼叫方式和我們呼叫 Elixir 函式一樣,只有一個小差別:Erlang 模組的名稱是 snake_case 的原子。舉例來說,若要從 math 模組呼叫 Erlang 的 pi/0 函式,可以這樣寫:
:math.pi()
# => 3.141592653589793
最常用、而且 Elixir 沒有對應版本的 Erlang 函式有:
:timer.sleep/1:讓行程暫停指定的毫秒數。:rand.uniform/0:產生一個隨機浮點數 x,其中 0.0 <= x < 1.0。:io_lib.format/2:提供 C 風格的字串格式化(使用控制序列)。用這個函式,我們可以把整數以 2 到 36 之間的任意進位印出,也可以用想要的小數位數格式化浮點數。注意,這個函式和許多 Erlang 函式一樣,回傳的是字元列表。math 模組,提供 sin/1、cos/1、log2/1、log10/1、pow/2 等數學函式。想探索 Erlang 的標準函式庫,可以閱讀 STDLIB 參考手冊。
瑪莉是電視影集 Star Trek: The Next Generation 的忠實粉絲。她經常玩紙筆角色扮演遊戲,在遊戲中她和朋友們會假扮成 Starship Enterprise 的船員。瑪莉的角色是 Captain Picard,這表示她必須寫艦長日誌。她很喜歡遊戲中發揮創意的部分,但不喜歡臨時憑空生出隨機資料。
幫瑪莉建立隨機產生器,用來產生艦長日誌中常見的資料吧。
Starship Enterprise 在航行途中會遇到許多行星。在 Star Trek 宇宙中,行星會依其特性分成不同等級。例如,地球是 M 級行星。所有可能的行星等級有:D、H、J、K、L、M、N、R、T 和 Y。
實作random_planet_class/0函式,它應該隨機回傳其中一個行星等級。
CaptainsLog.random_planet_class()
# => "K"
Enterprise(註冊編號 NCC-1701)可不是唯一在宇宙中飛行的星艦喔!當它與另一艘星艦會合時,瑪莉需要記錄那艘星艦的註冊編號。
註冊編號以「NCC-」為開頭,後面接著 1000 到 9999(含)之間的數字。
實作random_ship_registry_number/0函式,回傳隨機的星艦註冊編號。
CaptainsLog.random_ship_registry_number()
# => "NCC-1947"
如果日誌不記錄日期,那還有什麼用呢?
星曆是浮點數。Starship Enterprise 在 The Next Generation 第一季的冒險,發生在星曆 41000.0 到 42000.0 之間。「4」代表第 24 世紀,「1」代表第一季。
實作random_stardate/0函式,回傳介於 41000.0(含)與 42000.0(不含)之間的浮點數。
實作時應該使用 Erlang 函式。
CaptainsLog.random_stardate()
# => 41458.15721310934
在艦長日誌中,星曆通常會四捨五入到小數點後一位。
實作format_stardate/1函式,它會接收一個浮點數,並回傳將該數字四捨五入到小數點後一位的字串。
實作時應該使用 Erlang 函式。
CaptainsLog.format_stardate(41458.15721310934)
# => "41458.2"