Elixirは動的型付け言語なので、コンパイル時の型チェックは提供されていません。それでも型仕様は役に立ちます。型仕様には次のような役割があるからです。
型仕様は、関数定義の直前に@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 - アトムリテラル組み込みの特殊型、例えば:
char() - 0..0x10FFFFの範囲の整数charlist() - 文字の配列keyword() - 最初の要素がアトムである2要素のタプルの配列カスタム型
すべての型の完全なリストは、公式ドキュメントの「Typespecs」セクションにあります。
型仕様の引数には名前を付けることもできます。これは同じ型の引数が複数あるときに区別するのに便利です。
@spec to_hex({hue :: integer, saturation :: integer, lightness :: integer}) :: String.t()
カスタム型は、次の3つのモジュール属性のいずれかを使って定義できます。
@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()として定義されており、解析ツールにとってこの2つの型は同等ですが、Elixirの文字列を扱う関数をドキュメント化するには、String.t()の方が意図が伝わりやすい選択です。
一方、string()は別の型です。これはErlangの文字列で、Elixirでは文字リストとして知られています。型仕様ではstring()型を避け、代わりにcharlist()を使うべきです。
Dialyzerは、ErlangやElixirのコードにおける型エラーなどの問題を検出できる静的解析ツールです。ElixirプロジェクトでDialyzerを使う最も簡単な方法は、Dialyxirを使うことです。