檢視原始碼 模組

模組語法

Erlang 程式碼被劃分為模組。一個模組由一系列的屬性和函式宣告組成,每個都以句點 (.) 終止。

範例

-module(m).          % module attribute
-export([fact/1]).   % module attribute

fact(N) when N>0 ->  % beginning of function declaration
    N * fact(N-1);   %  |
fact(0) ->           %  |
    1.               % end of function declaration

有關函式宣告的說明,請參閱函式宣告語法

模組屬性

一個模組屬性定義了一個模組的特定屬性。

一個模組屬性由一個標籤和一個值組成。

-Tag(Value).

Tag 必須是一個原子,而 Value 必須是一個字面項。為了方便使用者自定義屬性,如果字面項 Value 的語法是 Name/Arity(其中 Name 是一個原子,Arity 是一個正整數),那麼項 Name/Arity 會被轉換為 {Name,Arity}

可以指定任何模組屬性。這些屬性儲存在編譯後的程式碼中,可以通過呼叫 Module:module_info(attributes) 或使用 STDLIB 中的 beam_lib 模組來檢索。

一些模組屬性具有預定義的含義。它們中的一些具有二元arity,但使用者定義的模組屬性必須具有一元arity。

預定義的模組屬性

預定義的模組屬性必須放置在任何函式宣告之前。

  • -module(Module). - 模組宣告,定義模組的名稱。名稱 Module,一個原子,必須與檔名相同,但要減去副檔名 .erl。否則,程式碼載入將無法按預期工作。

    這個屬性必須最先指定,並且是唯一強制性的屬性。

  • -export(Functions). - 匯出的函式。指定模組內定義的哪些函式可以從模組外部可見。

    Functions 是一個列表 [Name1/Arity1, ..., NameN/ArityN],其中每個 NameI 都是一個原子,而 ArityI 是一個整數。

  • -import(Module, Functions). - 匯入的函式。可以像本地函式一樣呼叫,也就是說,不帶任何模組前綴。

    Module,一個原子,指定要從哪個模組匯入函式。Functions 是一個與 export 類似的列表。

  • -moduledoc(Documentation).-moduledoc Documentation. - 此模組的使用者文件。 Documentation 的允許值與 -doc 相同。

    有關如何使用 -moduledoc 的更多詳細資訊,請參閱文件

  • -compile(Options). - 編譯器選項。Options 是一個單一選項或選項列表。編譯模組時,此屬性會新增到選項列表中。請參閱 Compiler 中的 compile 模組。

  • -vsn(Vsn). - 模組版本。Vsn 是任何字面項,可以使用 beam_lib:version/1 檢索。

    如果未指定此屬性,則版本預設為模組的 MD5 總和檢查碼。

  • -on_load(Function). - 此屬性命名一個函式,該函式會在模組載入時自動執行。如需更多資訊,請參閱在載入模組時執行函式

  • -nifs(Functions). - 指定模組中定義的哪些函式可以使用 erlang:load_nif/2 載入為 NIF。

    Functions 是一個列表 [Name1/Arity1, ..., NameN/ArityN],其中每個 NameI 都是一個原子,而 ArityI 是一個整數。

    雖然不是絕對必要,但建議在任何載入 NIF 的模組中使用 -nifs() 屬性,以便編譯器可以做出更好的優化決策。

    沒有必要在不載入 NIF 的模組中新增 -nifs([])。對於編譯器來說,在模組內未呼叫任何 erlang:load_nif/2 已經足以得出相同的結論。

    變更

    -nifs() 屬性的特殊含義是在 Erlang/OTP 25.0 中引入的。在之前的版本中,接受 -nifs(),但沒有特殊的含義。

行為模組屬性

可以指定模組是某個行為的回呼模組

-behaviour(Behaviour).

原子 Behaviour 給出行為的名稱,可以是使用者定義的行為或以下 OTP 標準行為之一

  • gen_server
  • gen_statem
  • gen_event
  • supervisor

也接受 behavior 的拼寫。

模組的回呼函式可以直接通過匯出的函式 behaviour_info/1 來指定

behaviour_info(callbacks) -> Callbacks.

或為每個回呼函式指定 -callback 屬性

-callback Name(Arguments) -> Result.

在此,Arguments 是零個或多個引數的列表。-callback 屬性是首選,因為額外的型別資訊可以被工具用來產生文件或尋找差異。

OTP 設計原則中了解有關行為和回呼模組的更多資訊。

記錄定義

記錄定義使用與模組屬性相同的語法

-record(Record, Fields).

記錄定義允許在模組中的任何位置,包括函式宣告之間。在記錄中了解更多資訊。

前置處理器

前置處理器使用與模組屬性相同的語法,它支援檔案包含、巨集和條件編譯

-include("SomeFile.hrl").
-define(Macro, Replacement).

前置處理器中了解更多資訊。

設定檔案和行號

用於更改預定義巨集 ?FILE?LINE 的語法與模組屬性相同

-file(File, Line).

此屬性供 Yecc 等工具使用,以通知編譯器原始程式是由另一個工具產生的。它還指出源檔案與原始使用者撰寫檔案的行之間的對應關係,原始程式是從該檔案產生的。

型別和函式規格

用於指定型別和函式規格的語法與模組屬性類似

-type my_type() :: atom() | integer().
-spec my_function(integer()) -> integer().

型別和函式規格中了解更多資訊。

此描述基於EEP8 - 型別和函式規格,該規格將不再進一步更新。

文件屬性

模組屬性 -doc(Documentation) 用於為函式/型別/回呼提供使用者文件

-doc("Example documentation").
example() -> ok.

該屬性應放置在其文件化的實體之前。Documentation 周圍的括號是可選的。Documentation 的允許值為

  • 字串常值utf-8 編碼的二進位字串 - 文件化實體的字串。允許任何字串常值,因此可以使用三重引號字串和轉換為字串常值的符號。以下範例是等效的

    -doc("Example \"docs\"").
    -doc(<<"Example \"docs\""/utf8>>).
    -doc ~S/Example "docs"/.
    -doc """
       Example "docs"
       """
    -doc ~B|Example "docs"|.

    為了清楚起見,建議對文件屬性使用普通的 "字串" 或三重引號字串。

  • {file, file:name/0 } - 讀取檔名內容並將其用作文件字串。

  • false - 將當前實體設定為隱藏,也就是說,它不應列為可用的函式,並且沒有文件。

  • Metadata ::map() - 關於當前實體的元數據。元數據中的一些鍵具有特殊含義。有關更多詳細資訊,請參閱模組文件元數據文件元數據

每個實體可以有多個元數據文件屬性,但只允許單個文件字串條目。

有關更多詳細資訊,請參閱 Erlang 參考手冊中的文件指南。

功能指令

雖然不是模組屬性,而是指令(因為它可能會影響語法),但有 -feature(..) 指令用於啟用和停用功能

語法與屬性類似,但有兩個引數

-feature(FeatureName, enable | disable).

請注意,功能指令只能出現在模組的前綴中。

註解

註解可以放置在模組中的任何位置,但不能放置在字串和引號原子中。註解以字元 % 開頭,並持續到但不包含下一個行尾。註解沒有任何影響,基本上等同於空白。

module_info/0 和 module_info/1 函式

編譯器會自動將兩個特殊的匯出函式插入到每個模組中

  • Module:module_info/0
  • Module:module_info/1

呼叫這些函式時,它們會檢索有關模組的資訊。

module_info/0

每個模組中的 module_info/0 函式都會傳回一個包含有關模組資訊的 {Key,Value} 元組列表。在撰寫本文時,該列表包含具有以下 Key 的元組:moduleattributescompileexportsmd5。元組的順序和數量可能會在沒有事先通知的情況下變更。

module_info/1

呼叫 module_info(Key)(其中 Key 是一個原子)會傳回關於模組的單個資訊。

Key 允許以下值

  • module - 傳回一個表示模組名稱的原子。

  • attributes - 返回一個 {AttributeName, ValueList} 元組的列表,其中 AttributeName 是屬性的名稱,而 ValueList 則是值的列表。請注意,如果模組中多次出現相同的屬性,則該屬性可能會在列表中多次出現,並且具有不同的值。

    如果模組使用 beam_lib:strip/1 移除資訊,屬性列表將會變為空。

  • compile - 返回一個包含模組編譯方式資訊的元組列表。如果模組使用 beam_lib:strip/1 移除資訊,此列表將為空。

  • md5 - 返回一個二進位值,表示模組的 MD5 校驗和。

  • exports - 返回一個 {Name, Arity} 元組的列表,其中包含模組中所有導出的函式。

  • functions - 返回一個 {Name, Arity} 元組的列表,其中包含模組中的所有函式。

  • nifs - 返回一個 {Name, Arity} 元組的列表,其中包含模組中所有的 NIF 函式。