軌道
/
Elixir
Elixir
/
課程大綱
/
型別規格
型別

型別規格 在 Elixir

1 個練習

關於 型別規格

Elixir 是一種動態型別語言,這表示它不提供編譯時期的型別檢查。儘管如此,型別規格仍然很有用,因為它們:

  • 可以作為文件。
  • 可以被 Dialyzer 之類的靜態分析工具使用,藉此找出可能的 bug。

你可以在函式定義之前,使用 @spec 模組屬性為函式加上型別規格。

@spec longer_than?(String.t(), non_neg_integer()) :: boolean()
def longer_than?(string, length), do: String.length(string) > length

型別

型別規格中允許的運算式:

  • 基本型別,例如:

    • boolean()
    • integer()、non_neg_integer()、pos_integer()、float()
    • list()
    • map()
    • any()
  • 型別的聯集:

    • 例如 integer() | list(integer())
  • 參數化型別:

    • 例如 list(integer()):整數的陣列
    • 例如 %{age: integer()}:在鍵 :age 下存放整數值的映射
  • 遠端型別(定義在某個模組中),例如:

  • 字面值,例如:

    • %{}:空的映射
    • []:空的陣列(但 [any()] 是非空的陣列)
    • 例如 :ok:atom 字面值
  • 內建的特殊型別,例如:

    • char():0..0x10FFFF 範圍內的整數
    • charlist():字元的陣列
    • keyword():由兩元素元組構成的陣列,其中第一個元素是 atom
  • 自訂型別

所有型別的完整清單可以在官方文件的「Typespecs」章節中找到。

為引數命名

型別規格中的引數也可以命名,這在區分多個同型別的引數時很有用。

@spec to_hex({hue :: integer, saturation :: integer, lightness :: integer}) :: String.t()

自訂型別

你可以使用以下三種模組屬性的其中一種來定義自訂型別:

  • @type:定義公開型別
  • @typep:定義私有型別
  • @opaque:定義結構為私有的公開型別
@type color :: {hue :: integer, saturation :: integer, lightness :: integer}

@spec to_hex(color()) :: String.t()

String.t() 與 binary() 與 string() 的比較

String.t() 是 Elixir 字串應該使用的正確型別,Elixir 字串是 UTF-8 編碼的二進位資料。技術上來說,String.t() 被定義為 binary(),對分析工具而言這兩種型別是等價的,但 String.t() 更能表達意圖,適合用來記錄處理 Elixir 字串的函式。

另一方面,string() 是另一種型別。它是 Erlang 的字串,在 Elixir 中稱為 charlist。在型別規格中應避免使用 string() 型別,改用 charlist()。

Dialyzer

Dialyzer 是一種靜態分析工具,可以偵測 Erlang 與 Elixir 程式碼中的型別錯誤等問題。在 Elixir 專案中使用 Dialyzer 最簡單的方式是透過 Dialyxir。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 型別規格